Robustified key behavior when the debugger is visible. Should now

properly ignore the "break into debugger" keypress and not allow
related characters to filter through. Removed some hacks related to
making that work in the past.

Changed osd_wait_for_debugger() to take a machine parameter and a
"firsttime" parameter, which is set to 1 the first time the function
is called after a break. The Windows debugger uses this to ensure
that the debugger has focus when you break into it.
This commit is contained in:
Aaron Giles 2008-07-17 16:09:52 +00:00
parent 4408b14d38
commit 517a24c0ef
12 changed files with 150 additions and 67 deletions

View File

@ -475,6 +475,22 @@ void CLIB_DECL debug_console_printf(const char *format, ...)
}
/*-------------------------------------------------
debug_console_vprintf - printfs the given
arguments using the format to the debug
console
-------------------------------------------------*/
void CLIB_DECL debug_console_vprintf(const char *format, va_list args)
{
vsprintf(giant_string_buffer, format, args);
text_buffer_print(console_textbuf, giant_string_buffer);
/* force an update of any console views */
debug_view_update_type(DVT_CONSOLE);
}
/*-------------------------------------------------
debug_console_printf_wrap - printfs the given
arguments using the format to the debug

View File

@ -13,6 +13,7 @@
#define __DEBUGCON_H__
#include "textbuf.h"
#include <stdarg.h>
/***************************************************************************
@ -87,6 +88,7 @@ const char * debug_cmderr_to_string(CMDERR error);
/* console management */
void CLIB_DECL debug_console_printf(const char *format, ...) ATTR_PRINTF(1,2);
void CLIB_DECL debug_console_vprintf(const char *format, va_list args);
void CLIB_DECL debug_console_printf_wrap(int wrapcol, const char *format, ...) ATTR_PRINTF(2,3);
text_buffer * debug_console_get_textbuf(void);

View File

@ -584,6 +584,8 @@ void debug_cpu_instruction_hook(running_machine *machine, offs_t curpc)
/* if we are supposed to halt, do it now */
if (global.execution_state == EXECUTION_STATE_STOPPED)
{
int firststop = TRUE;
/* reset any transient state */
reset_transient_flags(machine);
@ -597,7 +599,8 @@ void debug_cpu_instruction_hook(running_machine *machine, offs_t curpc)
{
/* clear the memory modified flag and wait */
global.memory_modified = FALSE;
osd_wait_for_debugger();
osd_wait_for_debugger(machine, firststop);
firststop = FALSE;
/* if something modified memory, update the screen */
if (global.memory_modified)
@ -921,9 +924,14 @@ const debug_cpu_info *debug_get_cpu_info(int cpunum)
the debugger on the next instruction
-------------------------------------------------*/
void debug_cpu_halt_on_next_instruction(running_machine *machine)
void debug_cpu_halt_on_next_instruction(running_machine *machine, const char *fmt, ...)
{
debug_console_printf("Internal breakpoint\n");
va_list arg;
va_start(arg, fmt);
debug_console_vprintf(fmt, arg);
va_end(arg);
global.execution_state = EXECUTION_STATE_STOPPED;
if (global.livecpu != NULL)
compute_debug_flags(machine, global.livecpu);

View File

@ -247,7 +247,7 @@ void debug_cpu_memory_write_hook(running_machine *machine, int cpunum, int space
int debug_cpu_within_instruction_hook(running_machine *machine);
const debug_cpu_info *debug_get_cpu_info(int cpunum);
void debug_cpu_halt_on_next_instruction(running_machine *machine);
void debug_cpu_halt_on_next_instruction(running_machine *machine, const char *fmt, ...) ATTR_PRINTF(2,3);
int debug_cpu_is_stopped(running_machine *machine);
void debug_cpu_trace_printf(int cpunum, const char *fmt, ...) ATTR_PRINTF(2,3);
void debug_cpu_source_script(const char *file);

View File

@ -83,7 +83,7 @@ INLINE void debugger_stop_cpu_hook(running_machine *machine, int cpunum)
INLINE void debugger_break(running_machine *machine)
{
if ((machine->debug_flags & DEBUG_FLAG_ENABLED) != 0)
debug_cpu_halt_on_next_instruction(machine);
debug_cpu_halt_on_next_instruction(machine, "Internal breakpoint");
}

View File

@ -56,8 +56,7 @@
#define INTERNAL_CODE(x) (INPUT_CODE_INTERNAL | ((x) & 0xfff))
#define INPUT_CODE_INVALID STANDARD_CODE(INVALID, 0, INVALID, NONE, INVALID)
/* Maximum number of axis/buttons/hats with ITEM_IDs for use by osd layer*/
/* maximum number of axis/buttons/hats with ITEM_IDs for use by osd layer */
#define INPUT_MAX_AXIS (8)
#define INPUT_MAX_BUTTONS (16)
#define INPUT_MAX_HATS (4)
@ -65,6 +64,8 @@
#define INPUT_MAX_ADD_ABSOLUTE (16)
#define INPUT_MAX_ADD_RELATIVE (16)
/***************************************************************************
CONSTANTS
***************************************************************************/

View File

@ -97,7 +97,7 @@
void osd_init(running_machine *machine);
void osd_wait_for_debugger(void);
void osd_wait_for_debugger(running_machine *machine, int firststop);

View File

@ -186,7 +186,6 @@ static debugwin_info *main_console;
static memorycombo_item *memorycombo;
static UINT8 debugger_active_countdown;
static UINT8 waiting_for_debugger;
static HFONT debug_font;
@ -199,9 +198,6 @@ static UINT32 vscroll_width;
static DWORD last_debugger_update;
static UINT8 temporarily_fake_that_we_are_not_visible;
//============================================================
// PROTOTYPES
@ -255,24 +251,32 @@ static void smart_show_all(BOOL show);
// osd_wait_for_debugger
//============================================================
void osd_wait_for_debugger(void)
void osd_wait_for_debugger(running_machine *machine, int firststop)
{
MSG message;
// create a console window
if (main_console == NULL)
console_create_window(Machine);
console_create_window(machine);
// update the views in the console to reflect the current CPU
if (main_console != NULL)
console_set_cpunum(Machine, cpu_getactivecpu());
console_set_cpunum(machine, cpu_getactivecpu());
// when we are first stopped, adjust focus to us
if (firststop && main_console != NULL)
{
SetForegroundWindow(main_console->wnd);
if (winwindow_has_focus())
SetFocus(main_console->editwnd);
}
// make sure the debug windows are visible
waiting_for_debugger = TRUE;
smart_show_all(TRUE);
// run input polling to ensure that our status is in sync
wininput_poll(Machine);
wininput_poll(machine);
// get and process messages
GetMessage(&message, NULL, 0, 0);
@ -291,17 +295,75 @@ void osd_wait_for_debugger(void)
// process everything else
default:
winwindow_dispatch_message(Machine, &message);
winwindow_dispatch_message(machine, &message);
break;
}
// mark the debugger as active
debugger_active_countdown = 2;
waiting_for_debugger = FALSE;
}
//============================================================
// debugwin_seq_pressed
//============================================================
int debugwin_seq_pressed(void)
{
const input_seq *seq = input_type_seq(Machine, IPT_UI_DEBUG_BREAK, 0, SEQ_TYPE_STANDARD);
int result = FALSE;
int invert = FALSE;
int first = TRUE;
int codenum;
// iterate over all of the codes
for (codenum = 0; codenum < ARRAY_LENGTH(seq->code); codenum++)
{
input_code code = seq->code[codenum];
// handle NOT
if (code == SEQCODE_NOT)
invert = TRUE;
// handle OR and END
else if (code == SEQCODE_OR || code == SEQCODE_END)
{
// if we have a positive result from the previous set, we're done
if (result || code == SEQCODE_END)
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
//============================================================
@ -420,20 +482,18 @@ void debugwin_show(int type)
// debugwin_update_during_game
//============================================================
void debugwin_update_during_game(void)
void debugwin_update_during_game(running_machine *machine)
{
// if we're running live, do some checks
if (!debug_cpu_is_stopped(Machine) && mame_get_phase(Machine) == MAME_PHASE_RUNNING)
if (!winwindow_has_focus() && !debug_cpu_is_stopped(machine) && mame_get_phase(machine) == MAME_PHASE_RUNNING)
{
// see if the interrupt key is pressed and break if it is
temporarily_fake_that_we_are_not_visible = TRUE;
if (ui_input_pressed(Machine, IPT_UI_DEBUG_BREAK))
if (debugwin_seq_pressed())
{
debugwin_info *info;
HWND focuswnd = GetFocus();
debugwin_info *info;
debugger_break(Machine);
debug_console_printf("User-initiated break\n");
debug_cpu_halt_on_next_instruction(machine, "User-initiated break\n");
// if we were focused on some window's edit box, reset it to default
for (info = window_list; info; info = info->next)
@ -443,33 +503,11 @@ void debugwin_update_during_game(void)
SendMessage(focuswnd, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
}
}
temporarily_fake_that_we_are_not_visible = FALSE;
}
}
//============================================================
// debugwin_is_debugger_visible
//============================================================
int debugwin_is_debugger_visible(void)
{
debugwin_info *info;
// a bit of hackiness to allow us to check key sequences even if we are visible
if (temporarily_fake_that_we_are_not_visible)
return 0;
// if any one of our windows is visible, return true
for (info = window_list; info; info = info->next)
if (IsWindowVisible(info->wnd))
return 1;
return 0;
}
//============================================================
// debug_window_create
//============================================================
@ -648,10 +686,10 @@ static LRESULT CALLBACK debug_window_proc(HWND wnd, UINT message, WPARAM wparam,
// char: ignore chars associated with keys we've handled
case WM_CHAR:
if (info->ignore_char_lparam != (lparam >> 16))
return DefWindowProc(wnd, message, wparam, lparam);
else
if (info->ignore_char_lparam == (lparam >> 16))
info->ignore_char_lparam = 0;
else if (waiting_for_debugger || !debugwin_seq_pressed())
return DefWindowProc(wnd, message, wparam, lparam);
break;
// activate: set the focus
@ -1403,15 +1441,15 @@ static LRESULT CALLBACK debug_view_proc(HWND wnd, UINT message, WPARAM wparam, L
// char: ignore chars associated with keys we've handled
case WM_CHAR:
{
if (info->owner->ignore_char_lparam != (lparam >> 16))
if (info->owner->ignore_char_lparam == (lparam >> 16))
info->owner->ignore_char_lparam = 0;
else if (waiting_for_debugger || !debugwin_seq_pressed())
{
if (wparam >= 32 && wparam < 127 && debug_view_get_property_UINT32(info->view, DVP_SUPPORTS_CURSOR))
debug_view_set_property_UINT32(info->view, DVP_CHARACTER, wparam);
else
return DefWindowProc(wnd, message, wparam, lparam);
}
else
info->owner->ignore_char_lparam = 0;
break;
}
@ -1531,10 +1569,10 @@ static LRESULT CALLBACK debug_edit_proc(HWND wnd, UINT message, WPARAM wparam, L
break;
default:
if (!(*info->handle_key)(info, wparam, lparam))
return CallWindowProc(info->original_editproc, wnd, message, wparam, lparam);
else
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;
@ -1543,7 +1581,9 @@ static LRESULT CALLBACK debug_edit_proc(HWND wnd, UINT message, WPARAM wparam, L
case WM_CHAR:
// ignore chars associated with keys we've handled
if (info->ignore_char_lparam != (lparam >> 16))
if (info->ignore_char_lparam == (lparam >> 16))
info->ignore_char_lparam = 0;
else if (waiting_for_debugger || !debugwin_seq_pressed())
{
switch (wparam)
{
@ -1593,8 +1633,6 @@ static LRESULT CALLBACK debug_edit_proc(HWND wnd, UINT message, WPARAM wparam, L
return CallWindowProc(info->original_editproc, wnd, message, wparam, lparam);
}
}
else
info->ignore_char_lparam = 0;
break;
// everything else: defaults
@ -2888,11 +2926,8 @@ static int global_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lpar
static int global_handle_key(debugwin_info *info, WPARAM wparam, LPARAM lparam)
{
int ignoreme;
/* ignore any keys that are received while the debug key is down */
ignoreme = ui_input_pressed(Machine, IPT_UI_DEBUG_BREAK);
if (ignoreme)
if (!waiting_for_debugger && debugwin_seq_pressed())
return 1;
switch (wparam)

View File

@ -26,7 +26,6 @@
void debugwin_init_windows(void);
void debugwin_destroy_windows(void);
void debugwin_show(int type);
void debugwin_update_during_game(void);
int debugwin_is_debugger_visible(void);
void debugwin_update_during_game(running_machine *machine);
#endif

View File

@ -418,7 +418,6 @@ static const int win_key_trans_table[][4] =
};
//============================================================
// INLINE FUNCTIONS
//============================================================
@ -699,6 +698,27 @@ BOOL wininput_handle_raw(HANDLE device)
}
//============================================================
// wininput_vkey_for_mame_code
//============================================================
int wininput_vkey_for_mame_code(input_code code)
{
// only works for keyboard switches
if (INPUT_CODE_DEVCLASS(code) == DEVICE_CLASS_KEYBOARD && INPUT_CODE_ITEMCLASS(code) == ITEM_CLASS_SWITCH)
{
input_item_id id = INPUT_CODE_ITEMID(code);
int tablenum;
// scan the table for a match
for (tablenum = 0; tablenum < ARRAY_LENGTH(win_key_trans_table); tablenum++)
if (win_key_trans_table[tablenum][MAME_KEY] == id)
return win_key_trans_table[tablenum][VIRTUAL_KEY];
}
return 0;
}
//============================================================
// osd_customize_mapping_list
//============================================================

View File

@ -23,5 +23,7 @@ BOOL wininput_handle_raw(HANDLE device);
int wininput_should_hide_mouse(void);
int wininput_vkey_for_mame_code(input_code code);
#endif /* __INPUT_H */

View File

@ -354,7 +354,7 @@ void winwindow_process_events(running_machine *machine, int ingame)
// if we're running, disable some parts of the debugger
if (ingame && (machine->debug_flags & DEBUG_FLAG_ENABLED) != 0)
debugwin_update_during_game();
debugwin_update_during_game(machine);
// remember the last time we did this
last_event_check = GetTickCount();