From 7c81353d9c26c35e73c7de44ad9d903671be4a8c Mon Sep 17 00:00:00 2001 From: Andrew Gardner Date: Wed, 16 Jan 2013 04:37:30 +0000 Subject: [PATCH] QT Debugger improvements. [Andrew Gardner] - Fixed disassembly window not following PC correctly. - Switched font to Courier New since it seems more universal. - Fixed gaps between rendered text characters. - Plumbed mouse handling through the debugger core (clicking selects). - Made the Enter key behave like old SDL debugger; silently steps. --- src/emu/debug/debugvw.c | 69 +++-- src/emu/debug/debugvw.h | 123 +++++---- src/emu/debug/dvdisasm.c | 64 +++-- src/emu/debug/dvdisasm.h | 33 +-- src/emu/debug/dvmemory.c | 108 +++++--- src/emu/debug/dvmemory.h | 47 ++-- src/osd/sdl/debugqtmainwindow.c | 454 ++++++++++++++++---------------- src/osd/sdl/debugqtview.c | 360 ++++++++++++++----------- src/osd/sdl/debugqtview.h | 35 ++- src/osd/sdl/sdl.mak | 1 + 10 files changed, 711 insertions(+), 583 deletions(-) diff --git a/src/emu/debug/debugvw.c b/src/emu/debug/debugvw.c index 88d57258f06..7cf655d908f 100644 --- a/src/emu/debug/debugvw.c +++ b/src/emu/debug/debugvw.c @@ -61,9 +61,9 @@ debug_view_source::debug_view_source(const char *name, device_t *device) : m_next(NULL), - m_name(name), - m_device(device), - m_is_octal(false) + m_name(name), + m_device(device), + m_is_octal(false) { device_execute_interface *intf; if (device && device->interface(intf)) @@ -92,9 +92,9 @@ debug_view_source::~debug_view_source() debug_view_source_list::debug_view_source_list(running_machine &machine) : m_machine(machine), - m_head(NULL), - m_tail(NULL), - m_count(0) + m_head(NULL), + m_tail(NULL), + m_count(0) { } @@ -206,24 +206,24 @@ const debug_view_source *debug_view_source_list::match_device(device_t *device) debug_view::debug_view(running_machine &machine, debug_view_type type, debug_view_osd_update_func osdupdate, void *osdprivate) : m_next(NULL), - m_type(type), - m_source(NULL), - m_source_list(machine), - m_osdupdate(osdupdate), - m_osdprivate(osdprivate), - m_visible(10,10), - m_total(10,10), - m_topleft(0,0), - m_cursor(0,0), - m_supports_cursor(false), - m_cursor_visible(false), - m_recompute(true), - m_update_level(0), - m_update_pending(true), - m_osd_update_pending(true), - m_viewdata(NULL), - m_viewdata_size(0), - m_machine(machine) + m_type(type), + m_source(NULL), + m_source_list(machine), + m_osdupdate(osdupdate), + m_osdprivate(osdprivate), + m_visible(10,10), + m_total(10,10), + m_topleft(0,0), + m_cursor(0,0), + m_supports_cursor(false), + m_cursor_visible(false), + m_recompute(true), + m_update_level(0), + m_update_pending(true), + m_osd_update_pending(true), + m_viewdata(NULL), + m_viewdata_size(0), + m_machine(machine) { // allocate memory for the buffer m_viewdata_size = m_visible.y * m_visible.x; @@ -429,6 +429,17 @@ void debug_view::view_char(int chval) } +//------------------------------------------------- +// view_click - handle a mouse click within the +// current view +//------------------------------------------------- + +void debug_view::view_click(const int button, const debug_view_xy& pos) +{ + // default does nothing +} + + //************************************************************************** // DEBUG VIEW MANAGER @@ -440,7 +451,7 @@ void debug_view::view_char(int chval) debug_view_manager::debug_view_manager(running_machine &machine) : m_machine(machine), - m_viewlist(NULL) + m_viewlist(NULL) { } @@ -562,10 +573,10 @@ debug_view *debug_view_manager::append(debug_view *view) debug_view_expression::debug_view_expression(running_machine &machine) : m_machine(machine), - m_dirty(true), - m_result(0), - m_parsed(debug_cpu_get_global_symtable(machine)), - m_string("0") + m_dirty(true), + m_result(0), + m_parsed(debug_cpu_get_global_symtable(machine)), + m_string("0") { } diff --git a/src/emu/debug/debugvw.h b/src/emu/debug/debugvw.h index cecc5adb7b0..aba8094aebe 100644 --- a/src/emu/debug/debugvw.h +++ b/src/emu/debug/debugvw.h @@ -72,31 +72,36 @@ enum debug_view_notification // attribute bits for debug_view_char.attrib -const UINT8 DCA_NORMAL = 0x00; // in Windows: black on white -const UINT8 DCA_CHANGED = 0x01; // in Windows: red foreground -const UINT8 DCA_SELECTED = 0x02; // in Windows: light red background -const UINT8 DCA_INVALID = 0x04; // in Windows: dark blue foreground -const UINT8 DCA_DISABLED = 0x08; // in Windows: darker foreground -const UINT8 DCA_ANCILLARY = 0x10; // in Windows: grey background -const UINT8 DCA_CURRENT = 0x20; // in Windows: yellow background -const UINT8 DCA_COMMENT = 0x40; // in Windows: green foreground +const UINT8 DCA_NORMAL = 0x00; // in Windows: black on white +const UINT8 DCA_CHANGED = 0x01; // in Windows: red foreground +const UINT8 DCA_SELECTED = 0x02; // in Windows: light red background +const UINT8 DCA_INVALID = 0x04; // in Windows: dark blue foreground +const UINT8 DCA_DISABLED = 0x08; // in Windows: darker foreground +const UINT8 DCA_ANCILLARY = 0x10; // in Windows: grey background +const UINT8 DCA_CURRENT = 0x20; // in Windows: yellow background +const UINT8 DCA_COMMENT = 0x40; // in Windows: green foreground // special characters that can be passed to process_char() -const int DCH_UP = 1; // up arrow -const int DCH_DOWN = 2; // down arrow -const int DCH_LEFT = 3; // left arrow -const int DCH_RIGHT = 4; // right arrow -const int DCH_PUP = 5; // page up -const int DCH_PDOWN = 6; // page down -const int DCH_HOME = 7; // home -const int DCH_CTRLHOME = 8; // ctrl+home -const int DCH_END = 9; // end -const int DCH_CTRLEND = 10; // ctrl+end -const int DCH_CTRLRIGHT = 11; // ctrl+right -const int DCH_CTRLLEFT = 12; // ctrl+left +const int DCH_UP = 1; // up arrow +const int DCH_DOWN = 2; // down arrow +const int DCH_LEFT = 3; // left arrow +const int DCH_RIGHT = 4; // right arrow +const int DCH_PUP = 5; // page up +const int DCH_PDOWN = 6; // page down +const int DCH_HOME = 7; // home +const int DCH_CTRLHOME = 8; // ctrl+home +const int DCH_END = 9; // end +const int DCH_CTRLEND = 10; // ctrl+end +const int DCH_CTRLRIGHT = 11; // ctrl+right +const int DCH_CTRLLEFT = 12; // ctrl+left +// special characters that can be passed to process_click() +const int DCK_LEFT_CLICK = 1; // left instantaneous click +const int DCK_RIGHT_CLICK = 2; // right instantaneous click +const int DCK_MIDDLE_CLICK = 3; // middle instantaneous click + //************************************************************************** // TYPE DEFINITIONS @@ -113,8 +118,8 @@ typedef void (*debug_view_osd_update_func)(debug_view &view, void *osdprivate); // a single "character" in the debug view has an ASCII value and an attribute byte struct debug_view_char { - UINT8 byte; - UINT8 attrib; + UINT8 byte; + UINT8 attrib; }; @@ -124,8 +129,8 @@ class debug_view_xy public: debug_view_xy(int _x = 0, int _y = 0) : x(_x), y(_y) { } - INT32 x; - INT32 y; + INT32 x; + INT32 y; }; @@ -149,10 +154,10 @@ public: private: // internal state - debug_view_source * m_next; // link to next item - astring m_name; // name of the source item - device_t * m_device; // associated device (if applicable) - bool m_is_octal; // is view in octal or hex + debug_view_source * m_next; // link to next item + astring m_name; // name of the source item + device_t * m_device; // associated device (if applicable) + bool m_is_octal; // is view in octal or hex }; @@ -181,10 +186,10 @@ public: private: // internal state - running_machine & m_machine; // reference to our machine - debug_view_source * m_head; // head of the list - debug_view_source * m_tail; // end of the tail - UINT32 m_count; // number of items in the list + running_machine & m_machine; // reference to our machine + debug_view_source * m_head; // head of the list + debug_view_source * m_tail; // end of the tail + UINT32 m_count; // number of items in the list }; @@ -221,6 +226,7 @@ public: void set_cursor_visible(bool visible = true); void set_source(const debug_view_source &source); void process_char(int character) { view_char(character); } + void process_click(int button, debug_view_xy pos) { view_click(button, pos); } protected: // internal updating helpers @@ -238,36 +244,37 @@ protected: virtual void view_update() = 0; virtual void view_notify(debug_view_notification type); virtual void view_char(int chval); + virtual void view_click(const int button, const debug_view_xy& pos); protected: // core view data - debug_view * m_next; // link to the next view - debug_view_type m_type; // type of view - const debug_view_source *m_source; // currently selected data source - debug_view_source_list m_source_list; // list of available data sources + debug_view * m_next; // link to the next view + debug_view_type m_type; // type of view + const debug_view_source *m_source; // currently selected data source + debug_view_source_list m_source_list; // list of available data sources // OSD data - debug_view_osd_update_func m_osdupdate; // callback for the update - void * m_osdprivate; // OSD-managed private data + debug_view_osd_update_func m_osdupdate; // callback for the update + void * m_osdprivate; // OSD-managed private data // visibility info - debug_view_xy m_visible; // visible size (in rows and columns) - debug_view_xy m_total; // total size (in rows and columns) - debug_view_xy m_topleft; // top-left visible position (in rows and columns) - debug_view_xy m_cursor; // cursor position - bool m_supports_cursor; // does this view support a cursor? - bool m_cursor_visible; // is the cursor visible? + debug_view_xy m_visible; // visible size (in rows and columns) + debug_view_xy m_total; // total size (in rows and columns) + debug_view_xy m_topleft; // top-left visible position (in rows and columns) + debug_view_xy m_cursor; // cursor position + bool m_supports_cursor; // does this view support a cursor? + bool m_cursor_visible; // is the cursor visible? // update info - bool m_recompute; // does this view require a recomputation? - UINT8 m_update_level; // update level; updates when this hits 0 - bool m_update_pending; // true if there is a pending update - bool m_osd_update_pending; // true if there is a pending update - debug_view_char * m_viewdata; // current array of view data - int m_viewdata_size; // number of elements of the viewdata array + bool m_recompute; // does this view require a recomputation? + UINT8 m_update_level; // update level; updates when this hits 0 + bool m_update_pending; // true if there is a pending update + bool m_osd_update_pending; // true if there is a pending update + debug_view_char * m_viewdata; // current array of view data + int m_viewdata_size; // number of elements of the viewdata array private: - running_machine & m_machine; // machine associated with this view + running_machine & m_machine; // machine associated with this view }; @@ -295,8 +302,8 @@ private: debug_view *append(debug_view *view); // internal state - running_machine & m_machine; // reference to our machine - debug_view * m_viewlist; // list of views + running_machine & m_machine; // reference to our machine + debug_view * m_viewlist; // list of views }; @@ -326,11 +333,11 @@ private: bool recompute(); // internal state - running_machine & m_machine; // reference to the machine - bool m_dirty; // true if the expression needs to be re-evaluated - UINT64 m_result; // last result from the expression - parsed_expression m_parsed; // parsed expression data - astring m_string; // copy of the expression string + running_machine & m_machine; // reference to the machine + bool m_dirty; // true if the expression needs to be re-evaluated + UINT64 m_result; // last result from the expression + parsed_expression m_parsed; // parsed expression data + astring m_string; // copy of the expression string }; diff --git a/src/emu/debug/dvdisasm.c b/src/emu/debug/dvdisasm.c index eec6f4787bc..53ecf9c5dd0 100644 --- a/src/emu/debug/dvdisasm.c +++ b/src/emu/debug/dvdisasm.c @@ -54,9 +54,9 @@ debug_view_disasm_source::debug_view_disasm_source(const char *name, device_t &device) : debug_view_source(name, &device), - m_device(device), - m_disasmintf(dynamic_cast(&device)), - m_space(device.memory().space(AS_PROGRAM)) + m_device(device), + m_disasmintf(dynamic_cast(&device)), + m_space(device.memory().space(AS_PROGRAM)) { } @@ -72,20 +72,20 @@ debug_view_disasm_source::debug_view_disasm_source(const char *name, device_t &d debug_view_disasm::debug_view_disasm(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate) : debug_view(machine, DVT_DISASSEMBLY, osdupdate, osdprivate), - m_right_column(DASM_RIGHTCOL_RAW), - m_backwards_steps(3), - m_dasm_width(DEFAULT_DASM_WIDTH), - m_last_direct_raw(NULL), - m_last_direct_decrypted(NULL), - m_last_change_count(0), - m_last_pcbyte(0), - m_divider1(0), - m_divider2(0), - m_divider3(0), - m_expression(machine), - m_allocated(0,0), - m_byteaddress(NULL), - m_dasm(NULL) + m_right_column(DASM_RIGHTCOL_RAW), + m_backwards_steps(3), + m_dasm_width(DEFAULT_DASM_WIDTH), + m_last_direct_raw(NULL), + m_last_direct_decrypted(NULL), + m_last_change_count(0), + m_last_pcbyte(0), + m_divider1(0), + m_divider2(0), + m_divider3(0), + m_expression(machine), + m_allocated(0,0), + m_byteaddress(NULL), + m_dasm(NULL) { // fail if no available sources enumerate_sources(); @@ -199,7 +199,7 @@ void debug_view_disasm::view_char(int chval) m_cursor.y = temp; break; - case DCH_HOME: // set the active column to the PC + case DCH_HOME: // set the active column to the PC { const debug_view_disasm_source &source = downcast(*m_source); offs_t pc = source.m_space.address_to_byte(source.m_device.safe_pc()) & source.m_space.logbytemask(); @@ -231,6 +231,32 @@ void debug_view_disasm::view_char(int chval) } +//------------------------------------------------- +// view_click - handle a mouse click within the +// current view +//------------------------------------------------- + +void debug_view_disasm::view_click(const int button, const debug_view_xy& pos) +{ + const debug_view_xy origcursor = m_cursor; + m_cursor = pos; + + /* cursor popup|toggle */ + bool cursorVisible = true; + if (m_cursor.y == origcursor.y) + { + cursorVisible = !m_cursor_visible; + } + + /* send a cursor changed notification */ + begin_update(); + m_cursor_visible = cursorVisible; + view_notify(VIEW_NOTIFY_CURSOR_CHANGED); + m_update_pending = true; + end_update(); +} + + //------------------------------------------------- // find_pc_backwards - back up the specified // number of instructions from the given PC @@ -367,7 +393,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines) m_total.x = m_divider2 + 1 + char_num * maxbytes_clamped + (maxbytes_clamped / minbytes - 1) + 1; } else if (m_right_column == DASM_RIGHTCOL_COMMENTS) - m_total.x = m_divider2 + 1 + 50; // DEBUG_COMMENT_MAX_LINE_LENGTH + m_total.x = m_divider2 + 1 + 50; // DEBUG_COMMENT_MAX_LINE_LENGTH else m_total.x = m_divider2 + 1; diff --git a/src/emu/debug/dvdisasm.h b/src/emu/debug/dvdisasm.h index 556e6907c7f..64d25295d2d 100644 --- a/src/emu/debug/dvdisasm.h +++ b/src/emu/debug/dvdisasm.h @@ -77,9 +77,9 @@ public: private: // internal state - device_t & m_device; // underlying device - device_disasm_interface *m_disasmintf; // disassembly interface - address_space & m_space; // address space to display + device_t & m_device; // underlying device + device_disasm_interface *m_disasmintf; // disassembly interface + address_space & m_space; // address space to display }; @@ -113,6 +113,7 @@ protected: virtual void view_update(); virtual void view_notify(debug_view_notification type); virtual void view_char(int chval); + virtual void view_click(const int button, const debug_view_xy& pos); private: // internal helpers @@ -122,19 +123,19 @@ private: bool recompute(offs_t pc, int startline, int lines); // internal state - disasm_right_column m_right_column; // right column contents - UINT32 m_backwards_steps; // number of backwards steps - UINT32 m_dasm_width; // width of the disassembly area - UINT8 * m_last_direct_raw; // last direct raw value - UINT8 * m_last_direct_decrypted;// last direct decrypted value - UINT32 m_last_change_count; // last comment change count - offs_t m_last_pcbyte; // last PC byte value - int m_divider1, m_divider2; // left and right divider columns - int m_divider3; // comment divider column - debug_view_expression m_expression; // expression-related information - debug_view_xy m_allocated; // allocated rows/columns - offs_t * m_byteaddress; // addresses of the instructions - char * m_dasm; // disassembled instructions + disasm_right_column m_right_column; // right column contents + UINT32 m_backwards_steps; // number of backwards steps + UINT32 m_dasm_width; // width of the disassembly area + UINT8 * m_last_direct_raw; // last direct raw value + UINT8 * m_last_direct_decrypted;// last direct decrypted value + UINT32 m_last_change_count; // last comment change count + offs_t m_last_pcbyte; // last PC byte value + int m_divider1, m_divider2; // left and right divider columns + int m_divider3; // comment divider column + debug_view_expression m_expression; // expression-related information + debug_view_xy m_allocated; // allocated rows/columns + offs_t * m_byteaddress; // addresses of the instructions + char * m_dasm; // disassembled instructions // constants static const int DEFAULT_DASM_LINES = 1000; diff --git a/src/emu/debug/dvmemory.c b/src/emu/debug/dvmemory.c index 949bf71e995..c0a6b045bd4 100644 --- a/src/emu/debug/dvmemory.c +++ b/src/emu/debug/dvmemory.c @@ -74,37 +74,37 @@ const debug_view_memory::memory_view_pos debug_view_memory::s_memory_pos_table[9 debug_view_memory_source::debug_view_memory_source(const char *name, address_space &space) : debug_view_source(name, &space.device()), - m_space(&space), - m_memintf(dynamic_cast(&space.device())), - m_base(NULL), - m_length(0), - m_offsetxor(0), - m_endianness(space.endianness()), - m_prefsize(space.data_width() / 8) + m_space(&space), + m_memintf(dynamic_cast(&space.device())), + m_base(NULL), + m_length(0), + m_offsetxor(0), + m_endianness(space.endianness()), + m_prefsize(space.data_width() / 8) { } debug_view_memory_source::debug_view_memory_source(const char *name, memory_region ®ion) : debug_view_source(name), - m_space(NULL), - m_memintf(NULL), - m_base(region), - m_length(region.bytes()), - m_offsetxor(NATIVE_ENDIAN_VALUE_LE_BE(region.width() - 1, 0)), - m_endianness(region.endianness()), - m_prefsize(MIN(region.width(), 8)) + m_space(NULL), + m_memintf(NULL), + m_base(region), + m_length(region.bytes()), + m_offsetxor(NATIVE_ENDIAN_VALUE_LE_BE(region.width() - 1, 0)), + m_endianness(region.endianness()), + m_prefsize(MIN(region.width(), 8)) { } debug_view_memory_source::debug_view_memory_source(const char *name, void *base, int element_size, int num_elements) : debug_view_source(name), - m_space(NULL), - m_memintf(NULL), - m_base(base), - m_length(element_size * num_elements), - m_offsetxor(0), - m_endianness(ENDIANNESS_NATIVE), - m_prefsize(MIN(element_size, 8)) + m_space(NULL), + m_memintf(NULL), + m_base(base), + m_length(element_size * num_elements), + m_offsetxor(0), + m_endianness(ENDIANNESS_NATIVE), + m_prefsize(MIN(element_size, 8)) { } @@ -120,15 +120,15 @@ debug_view_memory_source::debug_view_memory_source(const char *name, void *base, debug_view_memory::debug_view_memory(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate) : debug_view(machine, DVT_MEMORY, osdupdate, osdprivate), - m_expression(machine), - m_chunks_per_row(16), - m_bytes_per_chunk(1), - m_reverse_view(false), - m_ascii_view(true), - m_no_translation(false), - m_maxaddr(0), - m_bytes_per_row(16), - m_byte_offset(0) + m_expression(machine), + m_chunks_per_row(16), + m_bytes_per_chunk(1), + m_reverse_view(false), + m_ascii_view(true), + m_no_translation(false), + m_maxaddr(0), + m_bytes_per_row(16), + m_byte_offset(0) { // fail if no available sources enumerate_sources(); @@ -181,10 +181,10 @@ void debug_view_memory::enumerate_sources() break; // add pretty much anything that's not a timer (we may wish to cull other items later) - // also, don't trim the front of the name, it's important to know which VIA6522 we're looking at, e.g. - if (strncmp(itemname, "timer/", 6)) + // also, don't trim the front of the name, it's important to know which VIA6522 we're looking at, e.g. + if (strncmp(itemname, "timer/", 6)) { - name.cpy(itemname); + name.cpy(itemname); m_source_list.append(*auto_alloc(machine(), debug_view_memory_source(name, base, valsize, valcount))); } } @@ -425,6 +425,32 @@ void debug_view_memory::view_char(int chval) } +//------------------------------------------------- +// view_click - handle a mouse click within the +// current view +//------------------------------------------------- + +void debug_view_memory::view_click(const int button, const debug_view_xy& pos) +{ + const debug_view_xy origcursor = m_cursor; + m_cursor = pos; + + /* cursor popup|toggle */ + bool cursorVisible = true; + if (m_cursor.y == origcursor.y) + { + cursorVisible = !m_cursor_visible; + } + + /* send a cursor changed notification */ + begin_update(); + m_cursor_visible = cursorVisible; + view_notify(VIEW_NOTIFY_CURSOR_CHANGED); + m_update_pending = true; + end_update(); +} + + //------------------------------------------------- // recompute - recompute the internal data and // structure of the memory view @@ -627,10 +653,10 @@ bool debug_view_memory::read(UINT8 size, offs_t offs, UINT64 &data) { switch (size) { - case 1: data = debug_read_byte(*source.m_space, offs, !m_no_translation); break; - case 2: data = debug_read_word(*source.m_space, offs, !m_no_translation); break; - case 4: data = debug_read_dword(*source.m_space, offs, !m_no_translation); break; - case 8: data = debug_read_qword(*source.m_space, offs, !m_no_translation); break; + case 1: data = debug_read_byte(*source.m_space, offs, !m_no_translation); break; + case 2: data = debug_read_word(*source.m_space, offs, !m_no_translation); break; + case 4: data = debug_read_dword(*source.m_space, offs, !m_no_translation); break; + case 8: data = debug_read_qword(*source.m_space, offs, !m_no_translation); break; } } return ismapped; @@ -674,10 +700,10 @@ void debug_view_memory::write(UINT8 size, offs_t offs, UINT64 data) { switch (size) { - case 1: debug_write_byte(*source.m_space, offs, data, !m_no_translation); break; - case 2: debug_write_word(*source.m_space, offs, data, !m_no_translation); break; - case 4: debug_write_dword(*source.m_space, offs, data, !m_no_translation); break; - case 8: debug_write_qword(*source.m_space, offs, data, !m_no_translation); break; + case 1: debug_write_byte(*source.m_space, offs, data, !m_no_translation); break; + case 2: debug_write_word(*source.m_space, offs, data, !m_no_translation); break; + case 4: debug_write_dword(*source.m_space, offs, data, !m_no_translation); break; + case 8: debug_write_qword(*source.m_space, offs, data, !m_no_translation); break; } return; } diff --git a/src/emu/debug/dvmemory.h b/src/emu/debug/dvmemory.h index 66aac33e8f3..b370fdb51a9 100644 --- a/src/emu/debug/dvmemory.h +++ b/src/emu/debug/dvmemory.h @@ -60,13 +60,13 @@ public: address_space *space() const { return m_space; } private: - address_space *m_space; // address space we reference (if any) - device_memory_interface *m_memintf; // pointer to the memory interface of the device - void * m_base; // pointer to memory base - offs_t m_length; // length of memory - offs_t m_offsetxor; // XOR to apply to offsets - endianness_t m_endianness; // endianness of memory - UINT8 m_prefsize; // preferred bytes per chunk + address_space *m_space; // address space we reference (if any) + device_memory_interface *m_memintf; // pointer to the memory interface of the device + void * m_base; // pointer to memory base + offs_t m_length; // length of memory + offs_t m_offsetxor; // XOR to apply to offsets + endianness_t m_endianness; // endianness of memory + UINT8 m_prefsize; // preferred bytes per chunk }; @@ -101,6 +101,7 @@ protected: virtual void view_notify(debug_view_notification type); virtual void view_update(); virtual void view_char(int chval); + virtual void view_click(const int button, const debug_view_xy& pos); private: struct cursor_pos @@ -126,31 +127,31 @@ private: void write(UINT8 size, offs_t offs, UINT64 data); // internal state - debug_view_expression m_expression; // expression describing the start address - UINT32 m_chunks_per_row; // number of chunks displayed per line - UINT8 m_bytes_per_chunk; // bytes per chunk - bool m_reverse_view; // reverse-endian view? - bool m_ascii_view; // display ASCII characters? - bool m_no_translation; // don't run addresses through the cpu translation hook - offs_t m_maxaddr; // (derived) maximum address to display - UINT32 m_bytes_per_row; // (derived) number of bytes displayed per line - UINT32 m_byte_offset; // (derived) offset of starting visible byte - astring m_addrformat; // (derived) format string to use to print addresses + debug_view_expression m_expression; // expression describing the start address + UINT32 m_chunks_per_row; // number of chunks displayed per line + UINT8 m_bytes_per_chunk; // bytes per chunk + bool m_reverse_view; // reverse-endian view? + bool m_ascii_view; // display ASCII characters? + bool m_no_translation; // don't run addresses through the cpu translation hook + offs_t m_maxaddr; // (derived) maximum address to display + UINT32 m_bytes_per_row; // (derived) number of bytes displayed per line + UINT32 m_byte_offset; // (derived) offset of starting visible byte + astring m_addrformat; // (derived) format string to use to print addresses struct section { bool contains(int x) const { return x >= m_pos && x < m_pos + m_width; } - INT32 m_pos; /* starting position */ - INT32 m_width; /* width of this section */ + INT32 m_pos; /* starting position */ + INT32 m_width; /* width of this section */ }; - section m_section[3]; // (derived) 3 sections to manage + section m_section[3]; // (derived) 3 sections to manage struct memory_view_pos { - UINT8 m_spacing; /* spacing between each entry */ - UINT8 m_shift[24]; /* shift for each character */ + UINT8 m_spacing; /* spacing between each entry */ + UINT8 m_shift[24]; /* shift for each character */ }; - static const memory_view_pos s_memory_pos_table[9]; // table for rendering at different chunk sizes + static const memory_view_pos s_memory_pos_table[9]; // table for rendering at different chunk sizes // constants static const int MEM_MAX_LINE_WIDTH = 1024; diff --git a/src/osd/sdl/debugqtmainwindow.c b/src/osd/sdl/debugqtmainwindow.c index d92bed9c88c..56ff9ed991d 100644 --- a/src/osd/sdl/debugqtmainwindow.c +++ b/src/osd/sdl/debugqtmainwindow.c @@ -4,299 +4,305 @@ #include "debug/dvdisasm.h" -MainWindow::MainWindow(device_t* processor, - running_machine* machine, - QWidget* parent) : - WindowQt(machine, parent), - m_historyIndex(0), - m_inputHistory() +MainWindow::MainWindow(device_t* processor, + running_machine* machine, + QWidget* parent) : + WindowQt(machine, parent), + m_historyIndex(0), + m_inputHistory() { - setGeometry(300, 300, 1000, 600); + setGeometry(300, 300, 1000, 600); - // - // The main frame and its input and log widgets - // - QFrame* mainWindowFrame = new QFrame(this); + // + // The main frame and its input and log widgets + // + QFrame* mainWindowFrame = new QFrame(this); - // The input line - m_inputEdit = new QLineEdit(mainWindowFrame); - connect(m_inputEdit, SIGNAL(returnPressed()), this, SLOT(executeCommand())); - m_inputEdit->installEventFilter(this); + // The input line + m_inputEdit = new QLineEdit(mainWindowFrame); + connect(m_inputEdit, SIGNAL(returnPressed()), this, SLOT(executeCommand())); + m_inputEdit->installEventFilter(this); - // The log view - m_consoleView = new DebuggerView(DVT_CONSOLE, - m_machine, - mainWindowFrame); - m_consoleView->setFocusPolicy(Qt::NoFocus); - m_consoleView->setPreferBottom(true); + // The log view + m_consoleView = new DebuggerView(DVT_CONSOLE, + m_machine, + mainWindowFrame); + m_consoleView->setFocusPolicy(Qt::NoFocus); + m_consoleView->setPreferBottom(true); - QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame); - vLayout->addWidget(m_consoleView); - vLayout->addWidget(m_inputEdit); - vLayout->setSpacing(3); - vLayout->setContentsMargins(4,0,4,2); + QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame); + vLayout->addWidget(m_consoleView); + vLayout->addWidget(m_inputEdit); + vLayout->setSpacing(3); + vLayout->setContentsMargins(4,0,4,2); - setCentralWidget(mainWindowFrame); + setCentralWidget(mainWindowFrame); - // - // Menu bars - // - // Create two commands - QAction* breakpointSetAct = new QAction("Toggle Breakpoint At Cursor", this); - QAction* runToCursorAct = new QAction("Run To Cursor", this); - breakpointSetAct->setShortcut(Qt::Key_F9); - runToCursorAct->setShortcut(Qt::Key_F4); - connect(breakpointSetAct, SIGNAL(triggered(bool)), this, SLOT(toggleBreakpointAtCursor(bool))); - connect(runToCursorAct, SIGNAL(triggered(bool)), this, SLOT(runToCursor(bool))); + // + // Menu bars + // + // Create two commands + QAction* breakpointSetAct = new QAction("Toggle Breakpoint At Cursor", this); + QAction* runToCursorAct = new QAction("Run To Cursor", this); + breakpointSetAct->setShortcut(Qt::Key_F9); + runToCursorAct->setShortcut(Qt::Key_F4); + connect(breakpointSetAct, SIGNAL(triggered(bool)), this, SLOT(toggleBreakpointAtCursor(bool))); + connect(runToCursorAct, SIGNAL(triggered(bool)), this, SLOT(runToCursor(bool))); - // Right bar options - QActionGroup* rightBarGroup = new QActionGroup(this); - QAction* rightActRaw = new QAction("Raw Opcodes", this); - QAction* rightActEncrypted = new QAction("Encrypted Opcodes", this); - QAction* rightActComments = new QAction("Comments", this); - rightActRaw->setCheckable(true); - rightActEncrypted->setCheckable(true); - rightActComments->setCheckable(true); - rightActRaw->setActionGroup(rightBarGroup); - rightActEncrypted->setActionGroup(rightBarGroup); - rightActComments->setActionGroup(rightBarGroup); - rightActRaw->setShortcut(QKeySequence("Ctrl+R")); - rightActEncrypted->setShortcut(QKeySequence("Ctrl+E")); - rightActComments->setShortcut(QKeySequence("Ctrl+C")); - rightActRaw->setChecked(true); - connect(rightBarGroup, SIGNAL(triggered(QAction*)), this, SLOT(rightBarChanged(QAction*))); + // Right bar options + QActionGroup* rightBarGroup = new QActionGroup(this); + QAction* rightActRaw = new QAction("Raw Opcodes", this); + QAction* rightActEncrypted = new QAction("Encrypted Opcodes", this); + QAction* rightActComments = new QAction("Comments", this); + rightActRaw->setCheckable(true); + rightActEncrypted->setCheckable(true); + rightActComments->setCheckable(true); + rightActRaw->setActionGroup(rightBarGroup); + rightActEncrypted->setActionGroup(rightBarGroup); + rightActComments->setActionGroup(rightBarGroup); + rightActRaw->setShortcut(QKeySequence("Ctrl+R")); + rightActEncrypted->setShortcut(QKeySequence("Ctrl+E")); + rightActComments->setShortcut(QKeySequence("Ctrl+C")); + rightActRaw->setChecked(true); + connect(rightBarGroup, SIGNAL(triggered(QAction*)), this, SLOT(rightBarChanged(QAction*))); - // Assemble the options menu - QMenu* optionsMenu = menuBar()->addMenu("&Options"); - optionsMenu->addAction(breakpointSetAct); - optionsMenu->addAction(runToCursorAct); - optionsMenu->addSeparator(); - optionsMenu->addActions(rightBarGroup->actions()); + // Assemble the options menu + QMenu* optionsMenu = menuBar()->addMenu("&Options"); + optionsMenu->addAction(breakpointSetAct); + optionsMenu->addAction(runToCursorAct); + optionsMenu->addSeparator(); + optionsMenu->addActions(rightBarGroup->actions()); - // - // Dock windows - // - QMenu* dockMenu = menuBar()->addMenu("Doc&ks"); + // + // Dock windows + // + QMenu* dockMenu = menuBar()->addMenu("Doc&ks"); - setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea); - setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); + setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea); + setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); - // The processor dock - QDockWidget* cpuDock = new QDockWidget("processor", this); - cpuDock->setAllowedAreas(Qt::LeftDockWidgetArea); - m_procFrame = new ProcessorDockWidget(m_machine, cpuDock); - cpuDock->setWidget(dynamic_cast(m_procFrame)); + // The processor dock + QDockWidget* cpuDock = new QDockWidget("processor", this); + cpuDock->setAllowedAreas(Qt::LeftDockWidgetArea); + m_procFrame = new ProcessorDockWidget(m_machine, cpuDock); + cpuDock->setWidget(dynamic_cast(m_procFrame)); - addDockWidget(Qt::LeftDockWidgetArea, cpuDock); - dockMenu->addAction(cpuDock->toggleViewAction()); + addDockWidget(Qt::LeftDockWidgetArea, cpuDock); + dockMenu->addAction(cpuDock->toggleViewAction()); - // The disassembly dock - QDockWidget* dasmDock = new QDockWidget("dasm", this); - dasmDock->setAllowedAreas(Qt::TopDockWidgetArea); - m_dasmFrame = new DasmDockWidget(m_machine, dasmDock); - dasmDock->setWidget(m_dasmFrame); + // The disassembly dock + QDockWidget* dasmDock = new QDockWidget("dasm", this); + dasmDock->setAllowedAreas(Qt::TopDockWidgetArea); + m_dasmFrame = new DasmDockWidget(m_machine, dasmDock); + dasmDock->setWidget(m_dasmFrame); - addDockWidget(Qt::TopDockWidgetArea, dasmDock); - dockMenu->addAction(dasmDock->toggleViewAction()); + addDockWidget(Qt::TopDockWidgetArea, dasmDock); + dockMenu->addAction(dasmDock->toggleViewAction()); - // Window title - astring title; - title.printf("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag()); - setWindowTitle(title.cstr()); + // Window title + astring title; + title.printf("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag()); + setWindowTitle(title.cstr()); } void MainWindow::setProcessor(device_t* processor) { - // Cpu swap - m_procFrame->view()->view()->set_source(*m_procFrame->view()->view()->source_list().match_device(processor)); - m_dasmFrame->view()->view()->set_source(*m_dasmFrame->view()->view()->source_list().match_device(processor)); + // Cpu swap + m_procFrame->view()->view()->set_source(*m_procFrame->view()->view()->source_list().match_device(processor)); + m_dasmFrame->view()->view()->set_source(*m_dasmFrame->view()->view()->source_list().match_device(processor)); - // Scrollbar refresh - seems I should be able to do in the DebuggerView - m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y); - m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y); + // Scrollbar refresh - seems I should be able to do in the DebuggerView + m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y); + m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y); - // Window title - astring title; - title.printf("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag()); - setWindowTitle(title.cstr()); + // Window title + astring title; + title.printf("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag()); + setWindowTitle(title.cstr()); } // Used to intercept the user clicking 'X' in the upper corner void MainWindow::closeEvent(QCloseEvent* event) { - debugActQuit(); + debugActQuit(); } // Used to intercept the user hitting the up arrow in the input widget bool MainWindow::eventFilter(QObject* obj, QEvent* event) { - // Only filter keypresses - QKeyEvent* keyEvent = NULL; - if (event->type() == QEvent::KeyPress) - { - keyEvent = static_cast(event); - } - else - { - return QObject::eventFilter(obj, event); - } + // Only filter keypresses + QKeyEvent* keyEvent = NULL; + if (event->type() == QEvent::KeyPress) + { + keyEvent = static_cast(event); + } + else + { + return QObject::eventFilter(obj, event); + } - // Catch up & down keys - if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) - { - if (keyEvent->key() == Qt::Key_Up) - { - if (m_historyIndex > 0) - m_historyIndex--; - } - else if (keyEvent->key() == Qt::Key_Down) - { - if (m_historyIndex < m_inputHistory.size()) - m_historyIndex++; - } + // Catch up & down keys + if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) + { + if (keyEvent->key() == Qt::Key_Up) + { + if (m_historyIndex > 0) + m_historyIndex--; + } + else if (keyEvent->key() == Qt::Key_Down) + { + if (m_historyIndex < m_inputHistory.size()) + m_historyIndex++; + } - // Populate the input edit or clear it if you're at the end - if (m_historyIndex == m_inputHistory.size()) - { - m_inputEdit->setText(""); - } - else - { - m_inputEdit->setText(m_inputHistory[m_historyIndex]); - } - } - else if (keyEvent->key() == Qt::Key_Enter) - { - executeCommand(false); - } - else - { - return QObject::eventFilter(obj, event); - } - - return true; + // Populate the input edit or clear it if you're at the end + if (m_historyIndex == m_inputHistory.size()) + { + m_inputEdit->setText(""); + } + else + { + m_inputEdit->setText(m_inputHistory[m_historyIndex]); + } + } + else if (keyEvent->key() == Qt::Key_Enter) + { + executeCommand(false); + } + else + { + return QObject::eventFilter(obj, event); + } + + return true; } void MainWindow::toggleBreakpointAtCursor(bool changedTo) { - debug_view_disasm* dasmView = downcast(m_dasmFrame->view()->view()); - if (dasmView->cursor_visible()) - { - if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()) - { - offs_t address = downcast(dasmView)->selected_address(); - device_debug *cpuinfo = dasmView->source()->device()->debug(); + debug_view_disasm* dasmView = downcast(m_dasmFrame->view()->view()); + if (dasmView->cursor_visible()) + { + if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()) + { + offs_t address = downcast(dasmView)->selected_address(); + device_debug *cpuinfo = dasmView->source()->device()->debug(); - // Find an existing breakpoint at this address - INT32 bpindex = -1; - for (device_debug::breakpoint* bp = cpuinfo->breakpoint_first(); - bp != NULL; - bp = bp->next()) - { - if (address == bp->address()) - { - bpindex = bp->index(); - break; - } - } + // Find an existing breakpoint at this address + INT32 bpindex = -1; + for (device_debug::breakpoint* bp = cpuinfo->breakpoint_first(); + bp != NULL; + bp = bp->next()) + { + if (address == bp->address()) + { + bpindex = bp->index(); + break; + } + } - // If none exists, add a new one - astring command; - if (bpindex == -1) - { - command.printf("bpset 0x%X", address); - } - else - { - command.printf("bpclear 0x%X", bpindex); - } - debug_console_execute_command(*m_machine, command, 1); - } - } + // If none exists, add a new one + astring command; + if (bpindex == -1) + { + command.printf("bpset 0x%X", address); + } + else + { + command.printf("bpclear 0x%X", bpindex); + } + debug_console_execute_command(*m_machine, command, 1); + } + } - refreshAll(); + refreshAll(); } void MainWindow::runToCursor(bool changedTo) { - debug_view_disasm* dasmView = downcast(m_dasmFrame->view()->view()); - if (dasmView->cursor_visible()) - { - if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()) - { - offs_t address = downcast(dasmView)->selected_address(); - astring command; - command.printf("go 0x%X", address); - debug_console_execute_command(*m_machine, command, 1); - } - } + debug_view_disasm* dasmView = downcast(m_dasmFrame->view()->view()); + if (dasmView->cursor_visible()) + { + if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()) + { + offs_t address = downcast(dasmView)->selected_address(); + astring command; + command.printf("go 0x%X", address); + debug_console_execute_command(*m_machine, command, 1); + } + } } void MainWindow::rightBarChanged(QAction* changedTo) { - debug_view_disasm* dasmView = downcast(m_dasmFrame->view()->view()); - if (changedTo->text() == "Raw Opcodes") - { - dasmView->set_right_column(DASM_RIGHTCOL_RAW); - } - else if (changedTo->text() == "Encrypted Opcodes") - { - dasmView->set_right_column(DASM_RIGHTCOL_ENCRYPTED); - } - else if (changedTo->text() == "Comments") - { - dasmView->set_right_column(DASM_RIGHTCOL_COMMENTS); - } - m_dasmFrame->view()->viewport()->update(); + debug_view_disasm* dasmView = downcast(m_dasmFrame->view()->view()); + if (changedTo->text() == "Raw Opcodes") + { + dasmView->set_right_column(DASM_RIGHTCOL_RAW); + } + else if (changedTo->text() == "Encrypted Opcodes") + { + dasmView->set_right_column(DASM_RIGHTCOL_ENCRYPTED); + } + else if (changedTo->text() == "Comments") + { + dasmView->set_right_column(DASM_RIGHTCOL_COMMENTS); + } + m_dasmFrame->view()->viewport()->update(); } void MainWindow::executeCommand(bool withClear) { - debug_console_execute_command(*m_machine, - m_inputEdit->text().toLocal8Bit().data(), - true); + if (m_inputEdit->text() == "") + { + debug_cpu_get_visible_cpu(*m_machine)->debug()->single_step(); + return; + } + + debug_console_execute_command(*m_machine, + m_inputEdit->text().toLocal8Bit().data(), + true); - // Add history & set the index to be the top of the stack - addToHistory(m_inputEdit->text()); + // Add history & set the index to be the top of the stack + addToHistory(m_inputEdit->text()); - // Clear out the text and reset the history pointer only if asked - if (withClear) - { - m_inputEdit->clear(); - m_historyIndex = m_inputHistory.size(); - } + // Clear out the text and reset the history pointer only if asked + if (withClear) + { + m_inputEdit->clear(); + m_historyIndex = m_inputHistory.size(); + } - // Refresh - m_consoleView->viewport()->update(); - m_procFrame->view()->update(); - m_dasmFrame->view()->update(); + // Refresh + m_consoleView->viewport()->update(); + m_procFrame->view()->update(); + m_dasmFrame->view()->update(); } void MainWindow::addToHistory(const QString& command) { - if (command == "") - return; + if (command == "") + return; + + // Always push back when there is no previous history + if (m_inputHistory.size() == 0) + { + m_inputHistory.push_back(m_inputEdit->text()); + return; + } - // Always push back when there is no previous history - if (m_inputHistory.size() == 0) - { - m_inputHistory.push_back(m_inputEdit->text()); - return; - } - - // If there is previous history, make sure it's not what you just executed - if (m_inputHistory.back() != m_inputEdit->text()) - { - m_inputHistory.push_back(m_inputEdit->text()); - } + // If there is previous history, make sure it's not what you just executed + if (m_inputHistory.back() != m_inputEdit->text()) + { + m_inputHistory.push_back(m_inputEdit->text()); + } } diff --git a/src/osd/sdl/debugqtview.c b/src/osd/sdl/debugqtview.c index 9e0a072085f..c809e5e7953 100644 --- a/src/osd/sdl/debugqtview.c +++ b/src/osd/sdl/debugqtview.c @@ -3,197 +3,239 @@ #include "debugqtview.h" -DebuggerView::DebuggerView(const debug_view_type& type, - running_machine* machine, - QWidget* parent) : - QAbstractScrollArea(parent), - m_preferBottom(false), - m_view(NULL), - m_machine(machine) +DebuggerView::DebuggerView(const debug_view_type& type, + running_machine* machine, + QWidget* parent) : + QAbstractScrollArea(parent), + m_preferBottom(false), + m_view(NULL), + m_machine(machine) { - QFont viewFontRequest("Courier"); - viewFontRequest.setFixedPitch(true); - viewFontRequest.setPointSize(12); - setFont(viewFontRequest); + // I like setting the font per-view since it doesn't override the menuing fonts. + QFont viewFontRequest("Courier New"); + viewFontRequest.setFixedPitch(true); + viewFontRequest.setPointSize(11); + setFont(viewFontRequest); - m_view = m_machine->debug_view().alloc_view(type, - DebuggerView::debuggerViewUpdate, - this); + m_view = m_machine->debug_view().alloc_view(type, + DebuggerView::debuggerViewUpdate, + this); + + connect(verticalScrollBar(), SIGNAL(valueChanged(int)), + this, SLOT(verticalScrollSlot(int))); + connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), + this, SLOT(horizontalScrollSlot(int))); } void DebuggerView::paintEvent(QPaintEvent* event) { - // Tell the MAME debug view how much real estate is available - QFontMetrics actualFont = fontMetrics(); - const int fontWidth = MAX(1, actualFont.maxWidth()); - const int fontHeight = MAX(1, actualFont.height()); - m_view->set_visible_size(debug_view_xy(width()/fontWidth, height()/fontHeight)); + // Tell the MAME debug view how much real estate is available + QFontMetrics actualFont = fontMetrics(); + const int fontWidth = MAX(1, actualFont.maxWidth()); + const int fontHeight = MAX(1, actualFont.height()); + m_view->set_visible_size(debug_view_xy(width()/fontWidth, height()/fontHeight)); - // Handle the scroll bars - const int verticalScrollCharDiff = m_view->total_size().y - m_view->visible_size().y; - const int scrollSize = verticalScrollCharDiff < 0 ? 0 : verticalScrollCharDiff; - bool atEnd = false; - if (verticalScrollBar()->value() == verticalScrollBar()->maximum()) - { - atEnd = true; - } - verticalScrollBar()->setRange(0, scrollSize); - if (m_preferBottom && atEnd) - { - verticalScrollBar()->setValue(scrollSize); - } - m_view->set_visible_position(debug_view_xy(0, verticalScrollBar()->value())); + // Handle the scroll bars + const int verticalScrollCharDiff = m_view->total_size().y - m_view->visible_size().y; + const int scrollSize = verticalScrollCharDiff < 0 ? 0 : verticalScrollCharDiff; + bool atEnd = false; + if (verticalScrollBar()->value() == verticalScrollBar()->maximum()) + { + atEnd = true; + } + verticalScrollBar()->setRange(0, scrollSize); + if (m_preferBottom && atEnd) + { + verticalScrollBar()->setValue(scrollSize); + } - // Draw the viewport widget - QPainter painter(viewport()); - painter.fillRect(0, 0, width(), height(), QBrush(Qt::white)); - painter.setBackgroundMode(Qt::OpaqueMode); - painter.setBackground(QColor(255,255,255)); + // Draw the viewport widget + QPainter painter(viewport()); + painter.fillRect(0, 0, width(), height(), QBrush(Qt::white)); + painter.setBackgroundMode(Qt::OpaqueMode); + painter.setBackground(QColor(255,255,255)); - // Background control - QBrush bgBrush; - bgBrush.setStyle(Qt::SolidPattern); - painter.setPen(QPen(QColor(0,0,0))); + // Background control + QBrush bgBrush; + bgBrush.setStyle(Qt::SolidPattern); + painter.setPen(QPen(QColor(0,0,0))); - size_t viewDataOffset = 0; - const debug_view_xy& visibleCharDims = m_view->visible_size(); - for (int y = 0; y < visibleCharDims.y; y++) - { - for (int x = 0; x < visibleCharDims.x; x++) - { - const unsigned char textAttr = m_view->viewdata()[viewDataOffset].attrib; + size_t viewDataOffset = 0; + const debug_view_xy& visibleCharDims = m_view->visible_size(); + for (int y = 0; y < visibleCharDims.y; y++) + { + for (int x = 0; x < visibleCharDims.x; x++) + { + const unsigned char textAttr = m_view->viewdata()[viewDataOffset].attrib; - if (x == 0 || textAttr != m_view->viewdata()[viewDataOffset-1].attrib) - { - // Text color handling - QColor fgColor(0,0,0); - QColor bgColor(255,255,255); + if (x == 0 || textAttr != m_view->viewdata()[viewDataOffset-1].attrib) + { + // Text color handling + QColor fgColor(0,0,0); + QColor bgColor(255,255,255); - if(textAttr & DCA_ANCILLARY) - { - bgColor.setRgb(0xe0, 0xe0, 0xe0); - } - if(textAttr & DCA_SELECTED) - { - bgColor.setRgb(0xff, 0x80, 0x80); - } - if(textAttr & DCA_CURRENT) - { - bgColor.setRgb(0xff, 0xff, 0x00); - } - if(textAttr & DCA_CHANGED) - { - fgColor.setRgb(0xff, 0x00, 0x00); - } - if(textAttr & DCA_INVALID) - { - fgColor.setRgb(0x00, 0x00, 0xff); - } - if(textAttr & DCA_DISABLED) - { - fgColor.setRgb((fgColor.red() + bgColor.red()) >> 1, - (fgColor.green() + bgColor.green()) >> 1, - (fgColor.blue() + bgColor.blue()) >> 1); - } - if(textAttr & DCA_COMMENT) - { - fgColor.setRgb(0x00, 0x80, 0x00); - } + if(textAttr & DCA_ANCILLARY) + { + bgColor.setRgb(0xe0, 0xe0, 0xe0); + } + if(textAttr & DCA_SELECTED) + { + bgColor.setRgb(0xff, 0x80, 0x80); + } + if(textAttr & DCA_CURRENT) + { + bgColor.setRgb(0xff, 0xff, 0x00); + } + if(textAttr & DCA_CHANGED) + { + fgColor.setRgb(0xff, 0x00, 0x00); + } + if(textAttr & DCA_INVALID) + { + fgColor.setRgb(0x00, 0x00, 0xff); + } + if(textAttr & DCA_DISABLED) + { + fgColor.setRgb((fgColor.red() + bgColor.red()) >> 1, + (fgColor.green() + bgColor.green()) >> 1, + (fgColor.blue() + bgColor.blue()) >> 1); + } + if(textAttr & DCA_COMMENT) + { + fgColor.setRgb(0x00, 0x80, 0x00); + } - bgBrush.setColor(bgColor); - painter.setBackground(bgBrush); - painter.setPen(QPen(fgColor)); - } + bgBrush.setColor(bgColor); + painter.setBackground(bgBrush); + painter.setPen(QPen(fgColor)); + } - // There is a touchy interplay between font height, drawing difference, visible position, etc - // To test, set the bgcolor to something crazy and see where stuff gets drawn - painter.drawText(x*fontWidth, - y*fontHeight + fontHeight, - QString(m_view->viewdata()[viewDataOffset].byte)); - viewDataOffset++; - } - } + // Your character is not guaranteed to take up the entire fontWidth x fontHeight, so fill before. + painter.fillRect(x*fontWidth, y*fontHeight, fontWidth, fontHeight, bgBrush); + + // There is a touchy interplay between font height, drawing difference, visible position, etc + // Fonts don't get drawn "down and to the left" like boxes, so some wiggling is needed. + painter.drawText(x*fontWidth, + (y*fontHeight + (fontHeight*0.80)), + QString(m_view->viewdata()[viewDataOffset].byte)); + viewDataOffset++; + } + } } void DebuggerView::keyPressEvent(QKeyEvent* event) { - if (m_view == NULL) - return QWidget::keyPressEvent(event); + if (m_view == NULL) + return QWidget::keyPressEvent(event); - Qt::KeyboardModifiers keyMods = QApplication::keyboardModifiers(); - bool ctrlDown = keyMods.testFlag(Qt::ControlModifier); + Qt::KeyboardModifiers keyMods = QApplication::keyboardModifiers(); + const bool ctrlDown = keyMods.testFlag(Qt::ControlModifier); - int keyPress = -1; - switch (event->key()) + int keyPress = -1; + switch (event->key()) + { + case Qt::Key_Up: + keyPress = DCH_UP; + break; + case Qt::Key_Down: + keyPress = DCH_DOWN; + break; + case Qt::Key_Left: + keyPress = DCH_LEFT; + if (ctrlDown) keyPress = DCH_CTRLLEFT; + break; + case Qt::Key_Right: + keyPress = DCH_RIGHT; + if (ctrlDown) keyPress = DCH_CTRLRIGHT; + break; + case Qt::Key_PageUp: + keyPress = DCH_PUP; + break; + case Qt::Key_PageDown: + keyPress = DCH_PDOWN; + break; + case Qt::Key_Home: + keyPress = DCH_HOME; + if (ctrlDown) keyPress = DCH_CTRLHOME; + break; + case Qt::Key_End: + keyPress = DCH_END; + if (ctrlDown) keyPress = DCH_CTRLEND; + break; + case Qt::Key_0: keyPress = '0'; break; + case Qt::Key_1: keyPress = '1'; break; + case Qt::Key_2: keyPress = '2'; break; + case Qt::Key_3: keyPress = '3'; break; + case Qt::Key_4: keyPress = '4'; break; + case Qt::Key_5: keyPress = '5'; break; + case Qt::Key_6: keyPress = '6'; break; + case Qt::Key_7: keyPress = '7'; break; + case Qt::Key_8: keyPress = '8'; break; + case Qt::Key_9: keyPress = '9'; break; + case Qt::Key_A: keyPress = 'a'; break; + case Qt::Key_B: keyPress = 'b'; break; + case Qt::Key_C: keyPress = 'c'; break; + case Qt::Key_D: keyPress = 'd'; break; + case Qt::Key_E: keyPress = 'e'; break; + case Qt::Key_F: keyPress = 'f'; break; + default: + return QWidget::keyPressEvent(event); + } + + m_view->set_cursor_visible(true); + m_view->process_char(keyPress); + + // Catch the view up with the cursor + verticalScrollBar()->setValue(m_view->visible_position().y); + + viewport()->update(); + update(); +} + + +void DebuggerView::mousePressEvent(QMouseEvent* event) +{ + if (event->button() == Qt::LeftButton) { - case Qt::Key_Up: - keyPress = DCH_UP; - break; - case Qt::Key_Down: - keyPress = DCH_DOWN; - break; - case Qt::Key_Left: - keyPress = DCH_LEFT; - if (ctrlDown) keyPress = DCH_CTRLLEFT; - break; - case Qt::Key_Right: - keyPress = DCH_RIGHT; - if (ctrlDown) keyPress = DCH_CTRLRIGHT; - break; - case Qt::Key_PageUp: - keyPress = DCH_PUP; - break; - case Qt::Key_PageDown: - keyPress = DCH_PDOWN; - break; - case Qt::Key_Home: - keyPress = DCH_HOME; - if (ctrlDown) keyPress = DCH_CTRLHOME; - break; - case Qt::Key_End: - keyPress = DCH_END; - if (ctrlDown) keyPress = DCH_CTRLEND; - break; - case Qt::Key_0: keyPress = '0'; break; - case Qt::Key_1: keyPress = '1'; break; - case Qt::Key_2: keyPress = '2'; break; - case Qt::Key_3: keyPress = '3'; break; - case Qt::Key_4: keyPress = '4'; break; - case Qt::Key_5: keyPress = '5'; break; - case Qt::Key_6: keyPress = '6'; break; - case Qt::Key_7: keyPress = '7'; break; - case Qt::Key_8: keyPress = '8'; break; - case Qt::Key_9: keyPress = '9'; break; - case Qt::Key_A: keyPress = 'a'; break; - case Qt::Key_B: keyPress = 'b'; break; - case Qt::Key_C: keyPress = 'c'; break; - case Qt::Key_D: keyPress = 'd'; break; - case Qt::Key_E: keyPress = 'e'; break; - case Qt::Key_F: keyPress = 'f'; break; - default: - return QWidget::keyPressEvent(event); + QFontMetrics actualFont = fontMetrics(); + const int fontWidth = MAX(1, actualFont.maxWidth()); + const int fontHeight = MAX(1, actualFont.height()); + + debug_view_xy topLeft = m_view->visible_position(); + debug_view_xy clickViewPosition; + clickViewPosition.x = topLeft.x + (event->x() / fontWidth); + clickViewPosition.y = topLeft.y + (event->y() / fontHeight); + m_view->process_click(DCK_LEFT_CLICK, clickViewPosition); + + viewport()->update(); + update(); } +} - m_view->set_cursor_visible(true); - m_view->process_char(keyPress); - // Catch the view up with the cursor - verticalScrollBar()->setValue(m_view->visible_position().y); +void DebuggerView::verticalScrollSlot(int value) +{ + m_view->set_visible_position(debug_view_xy(horizontalScrollBar()->value(), value)); +} - viewport()->update(); - update(); + +void DebuggerView::horizontalScrollSlot(int value) +{ + m_view->set_visible_position(debug_view_xy(value, verticalScrollBar()->value())); } void DebuggerView::debuggerViewUpdate(debug_view& debugView, void* osdPrivate) { - // Get a handle to the DebuggerView being updated & redraw - DebuggerView* dView = (DebuggerView*)osdPrivate; - dView->verticalScrollBar()->setValue(dView->view()->visible_position().y); - dView->viewport()->update(); - dView->update(); + // Get a handle to the DebuggerView being updated & redraw + DebuggerView* dView = (DebuggerView*)osdPrivate; + dView->verticalScrollBar()->setValue(dView->view()->visible_position().y); + dView->viewport()->update(); + dView->update(); } + + diff --git a/src/osd/sdl/debugqtview.h b/src/osd/sdl/debugqtview.h index 5deab206dc7..1e926949114 100644 --- a/src/osd/sdl/debugqtview.h +++ b/src/osd/sdl/debugqtview.h @@ -8,31 +8,38 @@ class DebuggerView : public QAbstractScrollArea { + Q_OBJECT + public: - DebuggerView(const debug_view_type& type, - running_machine* machine, - QWidget* parent=NULL); - virtual ~DebuggerView() {} + DebuggerView(const debug_view_type& type, + running_machine* machine, + QWidget* parent=NULL); + virtual ~DebuggerView() {} - void paintEvent(QPaintEvent* event); + void paintEvent(QPaintEvent* event); - // Callback to allow MAME to refresh the view - static void debuggerViewUpdate(debug_view& debugView, void* osdPrivate); + // Callback to allow MAME to refresh the view + static void debuggerViewUpdate(debug_view& debugView, void* osdPrivate); - // Setters and accessors - void setPreferBottom(bool pb) { m_preferBottom = pb; } - debug_view* view() { return m_view; } + // Setters and accessors + void setPreferBottom(bool pb) { m_preferBottom = pb; } + debug_view* view() { return m_view; } protected: - void keyPressEvent(QKeyEvent* event); + void keyPressEvent(QKeyEvent* event); + void mousePressEvent(QMouseEvent* event); + +private slots: + void verticalScrollSlot(int value); + void horizontalScrollSlot(int value); private: - bool m_preferBottom; + bool m_preferBottom; - debug_view* m_view; - running_machine* m_machine; + debug_view* m_view; + running_machine* m_machine; }; diff --git a/src/osd/sdl/sdl.mak b/src/osd/sdl/sdl.mak index 831022a1ee3..b899cb97329 100644 --- a/src/osd/sdl/sdl.mak +++ b/src/osd/sdl/sdl.mak @@ -635,6 +635,7 @@ DEBUGOBJS = \ $(SDLOBJ)/debugqtdasmwindow.o \ $(SDLOBJ)/debugqtmainwindow.o \ $(SDLOBJ)/debugqtmemorywindow.o \ + $(SDLOBJ)/debugqtview.moc.o \ $(SDLOBJ)/debugqtwindow.moc.o \ $(SDLOBJ)/debugqtlogwindow.moc.o \ $(SDLOBJ)/debugqtdasmwindow.moc.o \