mirror of
https://github.com/holub/mame
synced 2025-06-04 03:46:29 +03:00
> From: atari_ace@frontier.com
> 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:
parent
40181d18cc
commit
921e6203a5
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user