> To: submit@mamedev.org
> CC: atariace@hotmail.com
> Subject: [patch] Cleanup natural keyboard support
> Date: Tue, 14 Dec 2010 07:20:08 -0800
> 
> Hi mamedev,
> 
> inputx_setup_natural_keyboard sets callbacks from the core into the
> drivers which lack machine or device pointers. This means that
> drivers that use this api can't completely place their state in
> non-global storage. This patch fixes that by adding the machine
> parameter to the callbacks, and places the implementation data into
> input_port_private as well.
> 
> This really only affects MESS, since nothing in MAME uses this api.
> 
> ~aa
This commit is contained in:
Aaron Giles 2011-01-27 08:13:06 +00:00
parent 40181d18cc
commit 921e6203a5
3 changed files with 104 additions and 87 deletions

View File

@ -245,31 +245,6 @@ struct _input_type_state
};
/* private input port state */
struct _input_port_private
{
/* global state */
UINT8 safe_to_read; /* clear at start; set after state is loaded */
/* types */
input_type_state * typestatelist; /* list of live type states */
input_type_state * type_to_typestate[__ipt_max][MAX_PLAYERS]; /* map from type/player to type state */
/* specific special global input states */
digital_joystick_state joystick_info[MAX_PLAYERS][DIGITAL_JOYSTICKS_PER_PLAYER]; /* joystick states */
/* frame time tracking */
attotime last_frame_time; /* time of the last frame callback */
attoseconds_t last_delta_nsec; /* nanoseconds that passed since the previous callback */
/* playback/record information */
mame_file * record_file; /* recording file (NULL if not recording) */
mame_file * playback_file; /* playback file (NULL if not recording) */
UINT64 playback_accumulated_speed;/* accumulated speed during playback */
UINT32 playback_accumulated_frames;/* accumulated frames during playback */
};
typedef struct _inputx_code inputx_code;
struct _inputx_code
{
@ -294,6 +269,41 @@ struct _char_info
const char *alternate; /* alternative string, in UTF-8 */
};
/* private input port state */
struct _input_port_private
{
/* global state */
UINT8 safe_to_read; /* clear at start; set after state is loaded */
/* types */
input_type_state * typestatelist; /* list of live type states */
input_type_state * type_to_typestate[__ipt_max][MAX_PLAYERS]; /* map from type/player to type state */
/* specific special global input states */
digital_joystick_state joystick_info[MAX_PLAYERS][DIGITAL_JOYSTICKS_PER_PLAYER]; /* joystick states */
/* frame time tracking */
attotime last_frame_time; /* time of the last frame callback */
attoseconds_t last_delta_nsec; /* nanoseconds that passed since the previous callback */
/* playback/record information */
mame_file * record_file; /* recording file (NULL if not recording) */
mame_file * playback_file; /* playback file (NULL if not recording) */
UINT64 playback_accumulated_speed;/* accumulated speed during playback */
UINT32 playback_accumulated_frames;/* accumulated frames during playback */
/* inputx */
inputx_code *codes;
key_buffer *keybuffer;
emu_timer *inputx_timer;
int (*queue_chars)(running_machine *machine, const unicode_char *text, size_t text_len);
int (*accept_char)(running_machine *machine, unicode_char ch);
int (*charqueue_empty)(running_machine *machine);
attotime current_rate;
};
/***************************************************************************
MACROS
***************************************************************************/
@ -609,14 +619,6 @@ static const char_info charinfo[] =
{ UCHAR_MAMEKEY(CANCEL), "Break", NULL } /* Break/Pause key */
};
static inputx_code *codes;
static key_buffer *keybuffer;
static emu_timer *inputx_timer;
static int (*queue_chars)(const unicode_char *text, size_t text_len);
static int (*accept_char)(unicode_char ch);
static int (*charqueue_empty)(void);
static attotime current_rate;
static TIMER_CALLBACK(inputx_timerproc);
@ -2391,13 +2393,14 @@ static void frame_update_callback(running_machine &machine)
static key_buffer *get_buffer(running_machine *machine)
{
input_port_private *portdata = machine->input_port_data;
assert(inputx_can_post(machine));
return (key_buffer *) keybuffer;
return (key_buffer *)portdata->keybuffer;
}
static const inputx_code *find_code(unicode_char ch)
static const inputx_code *find_code(inputx_code *codes, unicode_char ch)
{
int i;
@ -2417,6 +2420,7 @@ static const inputx_code *find_code(unicode_char ch)
static void input_port_update_hook(running_machine *machine, const input_port_config *port, input_port_value *digital)
{
input_port_private *portdata = machine->input_port_data;
const key_buffer *keybuf;
const inputx_code *code;
unicode_char ch;
@ -2432,7 +2436,7 @@ static void input_port_update_hook(running_machine *machine, const input_port_co
{
/* identify the character that is down right now, and its component codes */
ch = keybuf->buffer[keybuf->begin_pos];
code = find_code(ch);
code = find_code(portdata->codes, ch);
/* loop through this character's component codes */
if (code != NULL)
@ -4910,17 +4914,19 @@ int validate_natural_keyboard_statics(void)
static void clear_keybuffer(running_machine &machine)
{
keybuffer = NULL;
queue_chars = NULL;
codes = NULL;
input_port_private *portdata = machine.input_port_data;
portdata->keybuffer = NULL;
portdata->queue_chars = NULL;
portdata->codes = NULL;
}
static void setup_keybuffer(running_machine *machine)
{
inputx_timer = timer_alloc(machine, inputx_timerproc, NULL);
keybuffer = auto_alloc_clear(machine, key_buffer);
input_port_private *portdata = machine->input_port_data;
portdata->inputx_timer = timer_alloc(machine, inputx_timerproc, NULL);
portdata->keybuffer = auto_alloc_clear(machine, key_buffer);
machine->add_notifier(MACHINE_NOTIFY_EXIT, clear_keybuffer);
}
@ -4928,12 +4934,13 @@ static void setup_keybuffer(running_machine *machine)
void inputx_init(running_machine *machine)
{
codes = NULL;
inputx_timer = NULL;
queue_chars = NULL;
accept_char = NULL;
charqueue_empty = NULL;
keybuffer = NULL;
input_port_private *portdata = machine->input_port_data;
portdata->codes = NULL;
portdata->inputx_timer = NULL;
portdata->queue_chars = NULL;
portdata->accept_char = NULL;
portdata->charqueue_empty = NULL;
portdata->keybuffer = NULL;
if (machine->debug_flags & DEBUG_FLAG_ENABLED)
{
@ -4944,7 +4951,7 @@ void inputx_init(running_machine *machine)
/* posting keys directly only makes sense for a computer */
if (input_machine_has_keyboard(machine))
{
codes = build_codes(machine, machine->m_portlist.first());
portdata->codes = build_codes(machine, machine->m_portlist.first());
setup_keybuffer(machine);
}
}
@ -4952,33 +4959,37 @@ void inputx_init(running_machine *machine)
void inputx_setup_natural_keyboard(
int (*queue_chars_)(const unicode_char *text, size_t text_len),
int (*accept_char_)(unicode_char ch),
int (*charqueue_empty_)(void))
running_machine *machine,
int (*queue_chars)(running_machine *machine, const unicode_char *text, size_t text_len),
int (*accept_char)(running_machine *machine, unicode_char ch),
int (*charqueue_empty)(running_machine *machine))
{
queue_chars = queue_chars_;
accept_char = accept_char_;
charqueue_empty = charqueue_empty_;
input_port_private *portdata = machine->input_port_data;
portdata->queue_chars = queue_chars;
portdata->accept_char = accept_char;
portdata->charqueue_empty = charqueue_empty;
}
int inputx_can_post(running_machine *machine)
{
return queue_chars || codes;
input_port_private *portdata = machine->input_port_data;
return portdata->queue_chars || portdata->codes;
}
static int can_post_key_directly(unicode_char ch)
static int can_post_key_directly(running_machine *machine, unicode_char ch)
{
input_port_private *portdata = machine->input_port_data;
int rc = FALSE;
const inputx_code *code;
if (queue_chars)
if (portdata->queue_chars)
{
rc = accept_char ? accept_char(ch) : TRUE;
rc = portdata->accept_char ? (*portdata->accept_char)(machine, ch) : TRUE;
}
else
{
code = find_code(ch);
code = find_code(portdata->codes, ch);
if (code)
rc = code->field[0] != NULL;
}
@ -4987,7 +4998,7 @@ static int can_post_key_directly(unicode_char ch)
static int can_post_key_alternate(unicode_char ch)
static int can_post_key_alternate(running_machine *machine, unicode_char ch)
{
const char *s;
const char_info *ci;
@ -5004,21 +5015,21 @@ static int can_post_key_alternate(unicode_char ch)
rc = uchar_from_utf8(&uchar, s, strlen(s));
if (rc <= 0)
return 0;
if (!can_post_key_directly(uchar))
if (!can_post_key_directly(machine, uchar))
return 0;
s += rc;
}
return 1;
}
static attotime choose_delay(unicode_char ch)
static attotime choose_delay(input_port_private *portdata, unicode_char ch)
{
attoseconds_t delay = 0;
if (attotime_compare(current_rate, attotime_zero) != 0)
return current_rate;
if (attotime_compare(portdata->current_rate, attotime_zero) != 0)
return portdata->current_rate;
if (queue_chars)
if (portdata->queue_chars)
{
/* systems with queue_chars can afford a much smaller delay */
delay = DOUBLE_TO_ATTOSECONDS(0.01);
@ -5042,6 +5053,7 @@ static attotime choose_delay(unicode_char ch)
static void internal_post_key(running_machine *machine, unicode_char ch)
{
input_port_private *portdata = machine->input_port_data;
key_buffer *keybuf;
keybuf = get_buffer(machine);
@ -5049,7 +5061,7 @@ static void internal_post_key(running_machine *machine, unicode_char ch)
/* need to start up the timer? */
if (keybuf->begin_pos == keybuf->end_pos)
{
timer_adjust_oneshot(inputx_timer, choose_delay(ch), 0);
timer_adjust_oneshot(portdata->inputx_timer, choose_delay(portdata, ch), 0);
keybuf->status_keydown = 0;
}
@ -5070,13 +5082,14 @@ static int buffer_full(running_machine *machine)
static void inputx_postn_rate(running_machine *machine, const unicode_char *text, size_t text_len, attotime rate)
{
input_port_private *portdata = machine->input_port_data;
int last_cr = 0;
unicode_char ch;
const char *s;
const char_info *ci;
const inputx_code *code;
current_rate = rate;
portdata->current_rate = rate;
if (inputx_can_post(machine))
{
@ -5095,16 +5108,16 @@ static void inputx_postn_rate(running_machine *machine, const unicode_char *text
if (LOG_INPUTX)
{
code = find_code(ch);
code = find_code(portdata->codes, ch);
logerror("inputx_postn(): code=%i (%s) field->name='%s'\n", (int) ch, code_point_string(machine, ch), (code && code->field[0]) ? code->field[0]->name : "<null>");
}
if (can_post_key_directly(ch))
if (can_post_key_directly(machine, ch))
{
/* we can post this key in the queue directly */
internal_post_key(machine, ch);
}
else if (can_post_key_alternate(ch))
else if (can_post_key_alternate(machine, ch))
{
/* we can post this key with an alternate representation */
ci = find_charinfo(ch);
@ -5129,20 +5142,21 @@ static void inputx_postn_rate(running_machine *machine, const unicode_char *text
static TIMER_CALLBACK(inputx_timerproc)
{
input_port_private *portdata = machine->input_port_data;
key_buffer *keybuf;
attotime delay;
keybuf = get_buffer(machine);
if (queue_chars)
if (portdata->queue_chars)
{
/* the driver has a queue_chars handler */
while((keybuf->begin_pos != keybuf->end_pos) && queue_chars(&keybuf->buffer[keybuf->begin_pos], 1))
while((keybuf->begin_pos != keybuf->end_pos) && (*portdata->queue_chars)(machine, &keybuf->buffer[keybuf->begin_pos], 1))
{
keybuf->begin_pos++;
keybuf->begin_pos %= ARRAY_LENGTH(keybuf->buffer);
if (attotime_compare(current_rate, attotime_zero) != 0)
if (attotime_compare(portdata->current_rate, attotime_zero) != 0)
break;
}
}
@ -5164,16 +5178,17 @@ static TIMER_CALLBACK(inputx_timerproc)
/* need to make sure timerproc is called again if buffer not empty */
if (keybuf->begin_pos != keybuf->end_pos)
{
delay = choose_delay(keybuf->buffer[keybuf->begin_pos]);
timer_adjust_oneshot(inputx_timer, delay, 0);
delay = choose_delay(portdata, keybuf->buffer[keybuf->begin_pos]);
timer_adjust_oneshot(portdata->inputx_timer, delay, 0);
}
}
int inputx_is_posting(running_machine *machine)
{
input_port_private *portdata = machine->input_port_data;
const key_buffer *keybuf;
keybuf = get_buffer(machine);
return (keybuf->begin_pos != keybuf->end_pos) || (charqueue_empty && !charqueue_empty());
return (keybuf->begin_pos != keybuf->end_pos) || (portdata->charqueue_empty && !(*portdata->charqueue_empty)(machine));
}
/***************************************************************************
@ -5509,6 +5524,7 @@ static void execute_input(running_machine *machine, int ref, int params, const c
static void execute_dumpkbd(running_machine *machine, int ref, int params, const char *param[])
{
inputx_code *codes = machine->input_port_data->codes;
const char *filename;
FILE *file = NULL;
const inputx_code *code;

View File

@ -1175,10 +1175,10 @@ int input_machine_has_keyboard(running_machine *machine);
void inputx_init(running_machine *machine);
/* called by drivers to setup natural keyboard support */
void inputx_setup_natural_keyboard(
int (*queue_chars)(const unicode_char *text, size_t text_len),
int (*accept_char)(unicode_char ch),
int (*charqueue_empty)(void));
void inputx_setup_natural_keyboard(running_machine *machine,
int (*queue_chars)(running_machine *machine, const unicode_char *text, size_t text_len),
int (*accept_char)(running_machine *machine, unicode_char ch),
int (*charqueue_empty)(running_machine *machine));
/* validity checks */
int validate_natural_keyboard_statics(void);

View File

@ -305,9 +305,9 @@ static const extended_keyboard_code at_keyboard_extended_codes_set_2_3[]=
static void at_keyboard_queue_insert(UINT8 data);
static int at_keyboard_queue_size(void);
static int at_keyboard_queue_chars(const unicode_char *text, size_t text_len);
static int at_keyboard_accept_char(unicode_char ch);
static int at_keyboard_charqueue_empty(void);
static int at_keyboard_queue_chars(running_machine *machine, const unicode_char *text, size_t text_len);
static int at_keyboard_accept_char(running_machine *machine, unicode_char ch);
static int at_keyboard_charqueue_empty(running_machine *machine);
@ -339,7 +339,8 @@ void at_keyboard_init(running_machine *machine, AT_KEYBOARD_TYPE type)
keyboard.ports[i] = machine->port(buf);
}
inputx_setup_natural_keyboard(at_keyboard_queue_chars,
inputx_setup_natural_keyboard(machine,
at_keyboard_queue_chars,
at_keyboard_accept_char,
at_keyboard_charqueue_empty);
}
@ -967,7 +968,7 @@ static UINT8 unicode_char_to_at_keycode(unicode_char ch)
at_keyboard_queue_chars
***************************************************************************/
static int at_keyboard_queue_chars(const unicode_char *text, size_t text_len)
static int at_keyboard_queue_chars(running_machine *machine, const unicode_char *text, size_t text_len)
{
int i;
UINT8 b;
@ -1236,14 +1237,14 @@ INPUT_PORTS_END
Inputx stuff
***************************************************************************/
static int at_keyboard_accept_char(unicode_char ch)
static int at_keyboard_accept_char(running_machine *machine, unicode_char ch)
{
return unicode_char_to_at_keycode(ch) != 0;
}
static int at_keyboard_charqueue_empty(void)
static int at_keyboard_charqueue_empty(running_machine *machine)
{
return at_keyboard_queue_size() == 0;
}