diff options
author | 2008-05-15 16:25:03 +0000 | |
---|---|---|
committer | 2008-05-15 16:25:03 +0000 | |
commit | 096331c8562467a67fb5674f46dbb26bb032d2a6 (patch) | |
tree | 1f9329631b6fb62a81f4bdd894403389d2f70759 /src/emu/uimenu.c | |
parent | bc4b470ebbee405c6f48253acc225451f52a9b70 (diff) |
Restructured input port internals and cleaned up inptport.c:
* Input ports are now maintained hierarchically. At the top
level are input ports, which contain a list of fields. Each
field represents one or more bits of the port. Certain fields
such as DIP switches and configuration switches contain a
list of settings, which can be selected. DIP switch fields
can also contain a list of DIP switch locations.
* Normalized behavior of port overrides (via PORT_INCLUDE or
by defining multiple overlapping bits). All fields within a
port are kept in strict increasing bit order, so altered DIP
switches are now kept in the appropriate order. This addresses
MAMETesters bug 01671.
* Live port state is now fully separate from configured
state. This is manifested in a similar way to devices, where
a const list of ports can be managed either offline or live.
Each port has a pointer to an opaque set of live state which
is NULL when offline or valid when live. Each port also has
a running_machine * which is also NULL when offline.
* Because of this new arrangement, the conversion from tokens
to a list of ports now requires reasonably complex memory
allocation, so these port lists must be explicitly allocated
and freed (they are not mantained by automatic resource
allocation).
* Custom and changed callbacks now take a pointer to a field
config instead of a running machine. This provides more
information about what field triggered the change notification.
The machine can be found by referenced field->port->machine.
* The inptport.c module has been cleaned up and many
ambiguities resolved. Most of this is internal, though it did
result in osd_customize_inputport_list() being changed to
osd_customize_input_type_list(). The parameter to this function
is now a linked list instead of an array, and the structures
referenced have been reorganized somewhat.
* Updated config.c to pass machine parameters to its callbacks.
* Updated validity checks, XML output, and UI system to handle
the new structures.
* Moved large table of default input settings to a separate
include file inpttype.h.
* Removed gross hacks in trackfld and hyperspt NVRAM. These
may be broken as a result.
Diffstat (limited to 'src/emu/uimenu.c')
-rw-r--r-- | src/emu/uimenu.c | 752 |
1 files changed, 409 insertions, 343 deletions
diff --git a/src/emu/uimenu.c b/src/emu/uimenu.c index 94d5ed5ef27..9e964f0f484 100644 --- a/src/emu/uimenu.c +++ b/src/emu/uimenu.c @@ -39,6 +39,8 @@ #define VISIBLE_GAMES_IN_LIST 15 #define MAX_PHYSICAL_DIPS 10 +#define MAX_INPUT_PORTS 32 +#define MAX_BITS_PER_PORT 32 /* DIP switch rendering parameters */ #define DIP_SWITCH_HEIGHT 0.05f @@ -84,13 +86,16 @@ struct _menu_state typedef struct _input_item_data input_item_data; struct _input_item_data { - input_seq * seq; /* pointer to the sequence we are operating on */ - const input_seq *defseq; /* pointer to the sequence we are operating on */ + const input_type_desc *typedesc; /* reference to type description for global inputs */ + const input_field_config *field; /* reference to field for game inputs */ + int seqtype; /* sequence type */ + input_seq seq; /* copy of the live sequence */ + const input_seq *defseq; /* pointer to the default sequence */ const char * name; const char * seqname; - UINT16 sortorder; /* sorting information */ - UINT8 type; /* type of port */ - UINT8 invert; /* type of port */ + UINT16 sortorder; /* sorting information */ + UINT8 type; /* type of port */ + UINT8 invert; /* type of port */ }; @@ -152,42 +157,41 @@ static const rgb_t sel_bgcolor = MAKE_ARGB(0xe0,0x80,0x80,0x00); static void ui_menu_exit(running_machine *machine); /* menu handlers */ -static UINT32 menu_main(UINT32 state); -static UINT32 menu_input_groups(UINT32 state); -static UINT32 menu_input(UINT32 state); -static UINT32 menu_switches(UINT32 state); -static UINT32 menu_analog(UINT32 state); +static UINT32 menu_main(running_machine *machine, UINT32 state); +static UINT32 menu_input_groups(running_machine *machine, UINT32 state); +static UINT32 menu_input(running_machine *machine, UINT32 state); +static UINT32 menu_switches(running_machine *machine, UINT32 state); +static UINT32 menu_analog(running_machine *machine, UINT32 state); #ifndef MESS -static UINT32 menu_bookkeeping(UINT32 state); +static UINT32 menu_bookkeeping(running_machine *machine, UINT32 state); #endif -static UINT32 menu_game_info(UINT32 state); -static UINT32 menu_cheat(UINT32 state); -static UINT32 menu_memory_card(UINT32 state); -static UINT32 menu_video(UINT32 state); -static UINT32 menu_quit_game(UINT32 state); -static UINT32 menu_select_game(UINT32 state); +static UINT32 menu_game_info(running_machine *machine, UINT32 state); +static UINT32 menu_cheat(running_machine *machine, UINT32 state); +static UINT32 menu_memory_card(running_machine *machine, UINT32 state); +static UINT32 menu_video(running_machine *machine, UINT32 state); +static UINT32 menu_quit_game(running_machine *machine, UINT32 state); +static UINT32 menu_select_game(running_machine *machine, UINT32 state); #ifdef MESS -static UINT32 menu_file_manager(UINT32 state); +static UINT32 menu_file_manager(running_machine *machine, UINT32 state); #if HAS_WAVE -static UINT32 menu_tape_control(UINT32 state); +static UINT32 menu_tape_control(running_machine *machine, UINT32 state); #endif /* HAS_WAVE */ #endif /* MESS */ /* menu helpers */ static void menu_render_triangle(bitmap_t *dest, const bitmap_t *source, const rectangle *sbounds, void *param); -static int input_menu_get_items(input_item_data *itemlist, int group); -static int input_menu_get_game_items(input_item_data *itemlist); +static int input_menu_get_items(running_machine *machine, input_item_data *itemlist, int group); +static int input_menu_get_game_items(running_machine *machine, input_item_data *itemlist); static void input_menu_toggle_none_default(input_seq *selected_seq, input_seq *original_seq, const input_seq *selected_defseq); static int input_menu_compare_items(const void *i1, const void *i2); -static void switches_menu_add_item(ui_menu_item *item, const input_port_entry *in, int switch_entry, void *ref); -static void switches_menu_select_previous(input_port_entry *in, int switch_entry); -static void switches_menu_select_next(input_port_entry *in, int switch_entry); -//static int switches_menu_compare_items(const void *i1, const void *i2); -static void analog_menu_add_item(ui_menu_item *item, const input_port_entry *in, const char *append_string, int which_item); +static void switches_menu_add_item(ui_menu_item *item, const input_field_config *field); +static void switches_menu_select_previous(const input_field_config *field); +static void switches_menu_select_next(const input_field_config *field); +static void analog_menu_add_item(ui_menu_item *item, const input_field_config *field, const char *append_string, int which_item); /* DIP switch helpers */ -static void dip_switch_build_model(input_port_entry *entry, int item_is_selected); +static void dip_switch_build_model(const input_field_config *field, int item_is_selected); static void dip_switch_draw_one(float dip_menu_x1, float dip_menu_y1, float dip_menu_x2, float dip_menu_y2, int model_index); static void dip_switch_render(const menu_extra *extra, float x1, float y1, float x2, float y2); @@ -591,25 +595,25 @@ static void ui_menu_draw_text_box(const char *text) keys for a menu -------------------------------------------------*/ -int ui_menu_generic_keys(UINT32 *selected, int num_items, int visible_items) +int ui_menu_generic_keys(running_machine *machine, UINT32 *selected, int num_items, int visible_items) { /* hitting cancel or selecting the last item returns to the previous menu */ - if (input_ui_pressed(IPT_UI_CANCEL) || (*selected == num_items - 1 && input_ui_pressed(IPT_UI_SELECT))) + if (input_ui_pressed(machine, IPT_UI_CANCEL) || (*selected == num_items - 1 && input_ui_pressed(machine, IPT_UI_SELECT))) { *selected = ui_menu_stack_pop(); return 1; } /* up backs up by one item */ - if (input_ui_pressed_repeat(IPT_UI_UP, 6)) + if (input_ui_pressed_repeat(machine, IPT_UI_UP, 6)) *selected = (*selected + num_items - 1) % num_items; /* down advances by one item */ - if (input_ui_pressed_repeat(IPT_UI_DOWN, 6)) + if (input_ui_pressed_repeat(machine, IPT_UI_DOWN, 6)) *selected = (*selected + 1) % num_items; /* page up backs up by visible_items */ - if (input_ui_pressed_repeat(IPT_UI_PAGE_UP, 6)) + if (input_ui_pressed_repeat(machine, IPT_UI_PAGE_UP, 6)) { if (*selected >= visible_items - 1) *selected -= visible_items - 1; @@ -618,7 +622,7 @@ int ui_menu_generic_keys(UINT32 *selected, int num_items, int visible_items) } /* page down advances by visible_items */ - if (input_ui_pressed_repeat(IPT_UI_PAGE_DOWN, 6)) + if (input_ui_pressed_repeat(machine, IPT_UI_PAGE_DOWN, 6)) { *selected += visible_items - 1; if (*selected >= num_items) @@ -626,15 +630,15 @@ int ui_menu_generic_keys(UINT32 *selected, int num_items, int visible_items) } /* home goes to the start */ - if (input_ui_pressed(IPT_UI_HOME)) + if (input_ui_pressed(machine, IPT_UI_HOME)) *selected = 0; /* end goes to the last */ - if (input_ui_pressed(IPT_UI_END)) + if (input_ui_pressed(machine, IPT_UI_END)) *selected = num_items - 1; /* pause enables/disables pause */ - if (input_ui_pressed(IPT_UI_PAUSE)) + if (input_ui_pressed(machine, IPT_UI_PAUSE)) mame_pause(Machine, !mame_is_paused(Machine)); return 0; @@ -694,11 +698,11 @@ UINT32 ui_menu_ui_handler(running_machine *machine, UINT32 state) ui_menu_stack_push(menu_main, 0); /* update the menu state */ - newstate = (*menu_stack[menu_stack_index].handler)(menu_stack[menu_stack_index].state); + newstate = (*menu_stack[menu_stack_index].handler)(machine, menu_stack[menu_stack_index].state); menu_stack[menu_stack_index].state = newstate; /* if the menus are to be hidden, return a cancel here */ - if ((input_ui_pressed(IPT_UI_CONFIGURE) && !ui_menu_is_force_game_select()) || menu_stack[menu_stack_index].handler == NULL) + if ((input_ui_pressed(machine, IPT_UI_CONFIGURE) && !ui_menu_is_force_game_select()) || menu_stack[menu_stack_index].handler == NULL) return UI_HANDLER_CANCEL; return 0; @@ -752,7 +756,7 @@ int ui_menu_is_force_game_select(void) menu_main - main UI menu -------------------------------------------------*/ -static UINT32 menu_main(UINT32 state) +static UINT32 menu_main(running_machine *machine, UINT32 state) { #define ADD_MENU(name, _handler, _param) \ do { \ @@ -762,28 +766,29 @@ do { \ menu_items++; \ } while (0) + const input_port_config *port; + const input_field_config *field; menu_state handler_list[20]; ui_menu_item item_list[20]; int has_categories = FALSE; int has_configs = FALSE; int has_analog = FALSE; int has_dips = FALSE; - input_port_entry *in; int menu_items = 0; int visible_items; /* scan the input port array to see what options we need to enable */ - for (in = Machine->input_ports; in->type != IPT_END; in++) - if (input_port_active(in)) + for (port = machine->portconfig; port != NULL; port = port->next) + for (field = port->fieldlist; field != NULL; field = field->next) { - if (in->type == IPT_DIPSWITCH_NAME) + if (field->type == IPT_DIPSWITCH) has_dips = TRUE; - if (port_type_is_analog(in->type)) - has_analog = TRUE; - if (in->type == IPT_CONFIG_NAME) + if (field->type == IPT_CONFIG) has_configs = TRUE; - if (in->category > 0) + if (field->category > 0) has_categories = TRUE; + if (input_type_is_analog(field->type)) + has_analog = TRUE; } /* reset the menu */ @@ -795,12 +800,12 @@ do { \ /* add optional input-related menus */ if (has_dips) - ADD_MENU("Dip Switches", menu_switches, (IPT_DIPSWITCH_NAME << 16) | (IPT_DIPSWITCH_SETTING << 24)); + ADD_MENU("Dip Switches", menu_switches, IPT_DIPSWITCH << 16); if (has_configs) - ADD_MENU("Driver Configuration", menu_switches, (IPT_CONFIG_NAME << 16) | (IPT_CONFIG_SETTING << 24)); + ADD_MENU("Driver Configuration", menu_switches, IPT_CONFIG << 16); #ifdef MESS if (has_categories) - ADD_MENU("Categories", menu_switches, (IPT_CATEGORY_NAME << 16) | (IPT_CATEGORY_SETTING << 24)); + ADD_MENU("Categories", menu_switches, IPT_CATEGORY << 16); #endif if (has_analog) ADD_MENU("Analog Controls", menu_analog, 0); @@ -822,7 +827,7 @@ do { \ #if HAS_WAVE /* add tape control menu */ - if (device_find_from_machine(Machine, IO_CASSETTE)) + if (device_find_from_machine(machine, IO_CASSETTE)) ADD_MENU("Tape Control", menu_tape_control, 1); #endif /* HAS_WAVE */ #endif /* MESS */ @@ -835,7 +840,7 @@ do { \ ADD_MENU("Cheat", menu_cheat, 1); /* add memory card menu */ - if (Machine->config->memcard_handler != NULL) + if (machine->config->memcard_handler != NULL) ADD_MENU("Memory Card", menu_memory_card, 0); /* add reset and exit menus */ @@ -846,9 +851,9 @@ do { \ visible_items = ui_menu_draw(item_list, menu_items, state, NULL); /* handle the keys */ - if (ui_menu_generic_keys(&state, menu_items, visible_items)) + if (ui_menu_generic_keys(machine, &state, menu_items, visible_items)) return state; - if (input_ui_pressed(IPT_UI_SELECT)) + if (input_ui_pressed(machine, IPT_UI_SELECT)) return ui_menu_stack_push(handler_list[state].handler, handler_list[state].state); return state; @@ -862,7 +867,7 @@ do { \ groups -------------------------------------------------*/ -static UINT32 menu_input_groups(UINT32 state) +static UINT32 menu_input_groups(running_machine *machine, UINT32 state) { ui_menu_item item_list[IPG_TOTAL_GROUPS + 2]; int menu_items = 0; @@ -885,9 +890,9 @@ static UINT32 menu_input_groups(UINT32 state) visible_items = ui_menu_draw(item_list, menu_items, state, NULL); /* handle the keys */ - if (ui_menu_generic_keys(&state, menu_items, visible_items)) + if (ui_menu_generic_keys(machine, &state, menu_items, visible_items)) return state; - if (input_ui_pressed(IPT_UI_SELECT)) + if (input_ui_pressed(machine, IPT_UI_SELECT)) return ui_menu_stack_push(menu_input, state << 16); return state; @@ -898,7 +903,7 @@ static UINT32 menu_input_groups(UINT32 state) menu_input - display a menu for inputs -------------------------------------------------*/ -static UINT32 menu_input(UINT32 state) +static UINT32 menu_input(running_machine *machine, UINT32 state) { ui_menu_item item_list[MAX_INPUT_PORTS * MAX_BITS_PER_PORT / 2]; input_item_data item_data[MAX_INPUT_PORTS * MAX_BITS_PER_PORT / 2]; @@ -907,13 +912,19 @@ static UINT32 menu_input(UINT32 state) int record_next = (state >> 14) & 1; int polling = (state >> 15) & 1; int group = state >> 16; + int changed = FALSE; int visible_items; int menu_items; int item; /* get the list of items */ menu_string_pool_offset = 0; - menu_items = input_menu_get_items(item_data, group); + + /* an out of range group is special; it just means the game-specific inputs */ + if (group > IPG_TOTAL_GROUPS) + menu_items = input_menu_get_game_items(machine, item_data); + else + menu_items = input_menu_get_items(machine, item_data, group); /* build the menu */ memset(item_list, 0, sizeof(item_list)); @@ -954,10 +965,11 @@ static UINT32 menu_input(UINT32 state) input_seq newseq; /* if UI_CANCEL is pressed, abort */ - if (input_ui_pressed(IPT_UI_CANCEL)) + if (input_ui_pressed(machine, IPT_UI_CANCEL)) { record_next = polling = FALSE; - input_menu_toggle_none_default(selected_item_data->seq, &starting_seq, selected_item_data->defseq); + input_menu_toggle_none_default(&selected_item_data->seq, &starting_seq, selected_item_data->defseq); + changed = TRUE; } /* poll again; if finished, update the sequence */ @@ -965,7 +977,8 @@ static UINT32 menu_input(UINT32 state) { record_next = TRUE; polling = FALSE; - *selected_item_data->seq = newseq; + selected_item_data->seq = newseq; + changed = TRUE; } } @@ -975,28 +988,47 @@ static UINT32 menu_input(UINT32 state) int prevsel = selected; /* handle generic menu keys */ - if (ui_menu_generic_keys(&selected, menu_items, visible_items)) + if (ui_menu_generic_keys(machine, &selected, menu_items, visible_items)) return selected; /* if an item was selected, start polling on it */ - if (input_ui_pressed(IPT_UI_SELECT)) + if (input_ui_pressed(machine, IPT_UI_SELECT)) { - input_seq_poll_start((selected_item_data->type == INPUT_TYPE_ANALOG) ? ITEM_CLASS_ABSOLUTE : ITEM_CLASS_SWITCH, record_next ? selected_item_data->seq : NULL); - starting_seq = *selected_item_data->seq; + input_seq_poll_start((selected_item_data->type == INPUT_TYPE_ANALOG) ? ITEM_CLASS_ABSOLUTE : ITEM_CLASS_SWITCH, record_next ? &selected_item_data->seq : NULL); + starting_seq = selected_item_data->seq; polling = TRUE; } /* if the clear key was pressed, reset the selected item */ - if (input_ui_pressed(IPT_UI_CLEAR)) + if (input_ui_pressed(machine, IPT_UI_CLEAR)) { - input_menu_toggle_none_default(selected_item_data->seq, selected_item_data->seq, selected_item_data->defseq); + input_menu_toggle_none_default(&selected_item_data->seq, &selected_item_data->seq, selected_item_data->defseq); record_next = FALSE; + changed = TRUE; } /* if the selection changed, update and reset the "record first" flag */ if (selected != prevsel) record_next = FALSE; } + + /* if the sequence changed, update it */ + if (changed) + { + if (group > IPG_TOTAL_GROUPS) + { + input_field_user_settings settings; + + input_field_get_user_settings(selected_item_data->field, &settings); + settings.seq[selected_item_data->seqtype] = selected_item_data->seq; + input_field_set_user_settings(selected_item_data->field, &settings); + } + else + { + const input_type_desc *typedesc = selected_item_data->typedesc; + input_type_set_seq(machine, typedesc->type, typedesc->player, selected_item_data->seqtype, &selected_item_data->seq); + } + } return selected | (record_next << 14) | (polling << 15) | (group << 16); } @@ -1007,14 +1039,14 @@ static UINT32 menu_input(UINT32 state) switches -------------------------------------------------*/ -static UINT32 menu_switches(UINT32 state) +static UINT32 menu_switches(running_machine *machine, UINT32 state) { ui_menu_item item_list[MAX_INPUT_PORTS * MAX_BITS_PER_PORT / 2]; - int switch_entry = (state >> 24) & 0xff; int switch_name = (state >> 16) & 0xff; UINT32 selected = state & 0xffff; - input_port_entry *selected_in = NULL; - input_port_entry *in; + const input_port_config *port; + const input_field_config *field; + const input_field_config *selected_field = NULL; int menu_items = 0; int changed = FALSE; int visible_items; @@ -1026,18 +1058,18 @@ static UINT32 menu_switches(UINT32 state) memset(dip_switch_model, 0, sizeof(dip_switch_model)); /* loop over input ports and set up the current values */ - for (in = Machine->input_ports; in->type != IPT_END; in++) - if (in->type == switch_name && input_port_active(in) && input_port_condition(in)) - { - switches_menu_add_item(&item_list[menu_items], in, switch_entry, in); - if (in->type == IPT_DIPSWITCH_NAME) - dip_switch_build_model(in, menu_items == selected); - menu_items++; - } + for (port = machine->portconfig; port != NULL; port = port->next) + for (field = port->fieldlist; field != NULL; field = field->next) + if (field->type == switch_name && input_condition_true(machine, &field->condition)) + { + switches_menu_add_item(&item_list[menu_items], field); + if (field->type == IPT_DIPSWITCH) + dip_switch_build_model(field, menu_items == selected); + menu_items++; + } /* sort the list */ -// qsort(item_list, menu_items, sizeof(item_list[0]), switches_menu_compare_items); - selected_in = item_list[selected].ref; + selected_field = item_list[selected].ref; /* add an item to return */ item_list[menu_items++].text = "Return to Prior Menu"; @@ -1052,18 +1084,18 @@ static UINT32 menu_switches(UINT32 state) visible_items = ui_menu_draw(item_list, menu_items, selected, (dip_switch_model[0].dip_name) ? &extra : NULL); /* handle generic menu keys */ - if (ui_menu_generic_keys(&selected, menu_items, visible_items)) + if (ui_menu_generic_keys(machine, &selected, menu_items, visible_items)) return selected; /* handle left/right arrows */ - if (input_ui_pressed(IPT_UI_LEFT) && (item_list[selected].flags & MENU_FLAG_LEFT_ARROW)) + if (input_ui_pressed(machine, IPT_UI_LEFT) && (item_list[selected].flags & MENU_FLAG_LEFT_ARROW)) { - switches_menu_select_previous(selected_in, switch_entry); + switches_menu_select_previous(selected_field); changed = TRUE; } - if (input_ui_pressed(IPT_UI_RIGHT) && (item_list[selected].flags & MENU_FLAG_RIGHT_ARROW)) + if (input_ui_pressed(machine, IPT_UI_RIGHT) && (item_list[selected].flags & MENU_FLAG_RIGHT_ARROW)) { - switches_menu_select_next(selected_in, switch_entry); + switches_menu_select_next(selected_field); changed = TRUE; } @@ -1071,21 +1103,21 @@ static UINT32 menu_switches(UINT32 state) /* due to conditional DIPs changing things */ if (changed) { - int newsel = 0; - input_port_update_defaults(); - for (in = Machine->input_ports; in->type != IPT_END; in++) - if (in->type == switch_name && input_port_active(in) && input_port_condition(in)) - { - if (selected_in == in) + int newselected = 0; + for (port = machine->portconfig; port != NULL; port = port->next) + for (field = port->fieldlist; field != NULL; field = field->next) + if (field->type == switch_name && input_condition_true(machine, &field->condition)) { - selected = newsel; - break; + if (field == selected_field) + { + selected = newselected; + break; + } + newselected++; } - newsel++; - } } - return selected | (switch_name << 16) | (switch_entry << 24); + return selected | (switch_name << 16); } @@ -1094,11 +1126,12 @@ static UINT32 menu_switches(UINT32 state) control settings -------------------------------------------------*/ -static UINT32 menu_analog(UINT32 state) +static UINT32 menu_analog(running_machine *machine, UINT32 state) { ui_menu_item item_list[MAX_INPUT_PORTS * 4 * ANALOG_ITEM_COUNT]; - input_port_entry *selected_in = NULL; - input_port_entry *in; + const input_port_config *port; + const input_field_config *field; + const input_field_config *selected_field = NULL; int menu_items = 0; int selected_item = 0; int visible_items; @@ -1110,45 +1143,48 @@ static UINT32 menu_analog(UINT32 state) menu_string_pool_offset = 0; /* loop over input ports and add the items */ - for (in = Machine->input_ports; in->type != IPT_END; in++) - if (port_type_is_analog(in->type)) - { - use_autocenter = 0; - switch (in->type) + for (port = Machine->portconfig; port != NULL; port = port->next) + for (field = port->fieldlist; field != NULL; field = field->next) + if (input_type_is_analog(field->type)) { - /* Autocenter Speed is only used for these devices */ - case IPT_POSITIONAL: - case IPT_POSITIONAL_V: - if (in->analog.wraps) break; - - case IPT_PEDAL: - case IPT_PEDAL2: - case IPT_PEDAL3: - case IPT_PADDLE: - case IPT_PADDLE_V: - case IPT_AD_STICK_X: - case IPT_AD_STICK_Y: - case IPT_AD_STICK_Z: - use_autocenter = 1; - break; - } + use_autocenter = FALSE; + switch (field->type) + { + /* Autocenter Speed is only used for these devices */ + case IPT_POSITIONAL: + case IPT_POSITIONAL_V: + if (field->flags & ANALOG_FLAG_WRAPS) + break; + + case IPT_PEDAL: + case IPT_PEDAL2: + case IPT_PEDAL3: + case IPT_PADDLE: + case IPT_PADDLE_V: + case IPT_AD_STICK_X: + case IPT_AD_STICK_Y: + case IPT_AD_STICK_Z: + use_autocenter = TRUE; + break; + } - /* track the selected item */ - if (state >= menu_items && state < menu_items + 3 + use_autocenter) - { - selected_in = in; - selected_item = state - menu_items; - // shift menu for missing Autocenter - if (selected_item && !use_autocenter) selected_item++; - } + /* track the selected item */ + if (state >= menu_items && state < menu_items + 3 + use_autocenter) + { + selected_field = field; + selected_item = state - menu_items; + // shift menu for missing Autocenter + if (selected_item && !use_autocenter) + selected_item++; + } - /* add the needed items for each analog input */ - analog_menu_add_item(&item_list[menu_items++], in, "Digital Speed", ANALOG_ITEM_KEYSPEED); - if (use_autocenter) - analog_menu_add_item(&item_list[menu_items++], in, "Autocenter Speed", ANALOG_ITEM_CENTERSPEED); - analog_menu_add_item(&item_list[menu_items++], in, "Reverse", ANALOG_ITEM_REVERSE); - analog_menu_add_item(&item_list[menu_items++], in, "Sensitivity", ANALOG_ITEM_SENSITIVITY); - } + /* add the needed items for each analog input */ + analog_menu_add_item(&item_list[menu_items++], field, "Digital Speed", ANALOG_ITEM_KEYSPEED); + if (use_autocenter) + analog_menu_add_item(&item_list[menu_items++], field, "Autocenter Speed", ANALOG_ITEM_CENTERSPEED); + analog_menu_add_item(&item_list[menu_items++], field, "Reverse", ANALOG_ITEM_REVERSE); + analog_menu_add_item(&item_list[menu_items++], field, "Sensitivity", ANALOG_ITEM_SENSITIVITY); + } /* add an item to return */ item_list[menu_items++].text = "Return to Prior Menu"; @@ -1157,26 +1193,32 @@ static UINT32 menu_analog(UINT32 state) visible_items = ui_menu_draw(item_list, menu_items, state, NULL); /* handle generic menu keys */ - if (ui_menu_generic_keys(&state, menu_items, visible_items)) + if (ui_menu_generic_keys(machine, &state, menu_items, visible_items)) return state; /* handle left/right arrows */ - if (input_ui_pressed_repeat(IPT_UI_LEFT,6) && (item_list[state].flags & MENU_FLAG_LEFT_ARROW)) + if (input_ui_pressed_repeat(machine, IPT_UI_LEFT,6) && (item_list[state].flags & MENU_FLAG_LEFT_ARROW)) delta = -1; - if (input_ui_pressed_repeat(IPT_UI_RIGHT,6) && (item_list[state].flags & MENU_FLAG_RIGHT_ARROW)) + if (input_ui_pressed_repeat(machine, IPT_UI_RIGHT,6) && (item_list[state].flags & MENU_FLAG_RIGHT_ARROW)) delta = 1; if (input_code_pressed(KEYCODE_LSHIFT)) delta *= 10; /* adjust the appropriate value */ - if (delta != 0 && selected_in) + if (delta != 0 && selected_field != NULL) + { + input_field_user_settings settings; + + input_field_get_user_settings(selected_field, &settings); switch (selected_item) { - case ANALOG_ITEM_KEYSPEED: selected_in->analog.delta += delta; break; - case ANALOG_ITEM_CENTERSPEED: selected_in->analog.centerdelta += delta; break; - case ANALOG_ITEM_REVERSE: selected_in->analog.reverse += delta; break; - case ANALOG_ITEM_SENSITIVITY: selected_in->analog.sensitivity += delta; break; + case ANALOG_ITEM_KEYSPEED: settings.delta += delta; break; + case ANALOG_ITEM_CENTERSPEED: settings.centerdelta += delta; break; + case ANALOG_ITEM_REVERSE: settings.reverse += delta; break; + case ANALOG_ITEM_SENSITIVITY: settings.sensitivity += delta; break; } + input_field_set_user_settings(selected_field, &settings); + } return state; } @@ -1188,7 +1230,7 @@ static UINT32 menu_analog(UINT32 state) -------------------------------------------------*/ #ifndef MESS -static UINT32 menu_bookkeeping(UINT32 state) +static UINT32 menu_bookkeeping(running_machine *machine, UINT32 state) { char buf[2048]; char *bufptr = buf; @@ -1230,7 +1272,7 @@ static UINT32 menu_bookkeeping(UINT32 state) ui_menu_draw_text_box(buf); /* handle the keys */ - ui_menu_generic_keys(&selected, 1, 0); + ui_menu_generic_keys(machine, &selected, 1, 0); return selected; } #endif @@ -1241,20 +1283,20 @@ static UINT32 menu_bookkeeping(UINT32 state) game information -------------------------------------------------*/ -static UINT32 menu_game_info(UINT32 state) +static UINT32 menu_game_info(running_machine *machine, UINT32 state) { char buf[2048]; char *bufptr = buf; UINT32 selected = 0; /* add the game info */ - bufptr += sprintf_game_info(Machine, bufptr); + bufptr += sprintf_game_info(machine, bufptr); /* draw the text */ ui_menu_draw_text_box(buf); /* handle the keys */ - ui_menu_generic_keys(&selected, 1, 0); + ui_menu_generic_keys(machine, &selected, 1, 0); return selected; } @@ -1263,9 +1305,9 @@ static UINT32 menu_game_info(UINT32 state) menu_cheat - display a menu for cheat options -------------------------------------------------*/ -static UINT32 menu_cheat(UINT32 state) +static UINT32 menu_cheat(running_machine *machine, UINT32 state) { - int result = cheat_menu(Machine, state); + int result = cheat_menu(machine, state); if (result == 0) return ui_menu_stack_pop(); return result; @@ -1277,7 +1319,7 @@ static UINT32 menu_cheat(UINT32 state) card options -------------------------------------------------*/ -static UINT32 menu_memory_card(UINT32 state) +static UINT32 menu_memory_card(running_machine *machine, UINT32 state) { ui_menu_item item_list[5]; int menu_items = 0; @@ -1312,15 +1354,15 @@ static UINT32 menu_memory_card(UINT32 state) visible_items = ui_menu_draw(item_list, menu_items, selected, NULL); /* handle the keys */ - if (ui_menu_generic_keys(&selected, menu_items, visible_items)) + if (ui_menu_generic_keys(machine, &selected, menu_items, visible_items)) return selected; - if (selected == 0 && input_ui_pressed(IPT_UI_LEFT) && cardnum > 0) + if (selected == 0 && input_ui_pressed(machine, IPT_UI_LEFT) && cardnum > 0) cardnum--; - if (selected == 0 && input_ui_pressed(IPT_UI_RIGHT) && cardnum < 1000) + if (selected == 0 && input_ui_pressed(machine, IPT_UI_RIGHT) && cardnum < 1000) cardnum++; /* handle actions */ - if (input_ui_pressed(IPT_UI_SELECT)) + if (input_ui_pressed(machine, IPT_UI_SELECT)) { /* handle load */ if (selected == insertindex) @@ -1338,7 +1380,7 @@ static UINT32 menu_memory_card(UINT32 state) /* handle eject */ else if (selected == ejectindex) { - memcard_eject(Machine); + memcard_eject(machine); popmessage("Memory card ejected"); } @@ -1360,7 +1402,7 @@ static UINT32 menu_memory_card(UINT32 state) menu_video - display a menu for video options -------------------------------------------------*/ -static UINT32 menu_video(UINT32 state) +static UINT32 menu_video(running_machine *machine, UINT32 state) { ui_menu_item item_list[100]; render_target *targetlist[16]; @@ -1391,7 +1433,7 @@ static UINT32 menu_video(UINT32 state) /* if we only ended up with one, auto-select it */ if (menu_items == 1) - return menu_video(0 << 16 | render_target_get_view(render_target_get_indexed(0))); + return menu_video(machine, 0 << 16 | render_target_get_view(render_target_get_indexed(0))); /* add an item for moving the UI */ item_list[menu_items++].text = "Move User Interface"; @@ -1403,11 +1445,11 @@ static UINT32 menu_video(UINT32 state) visible_items = ui_menu_draw(item_list, menu_items, selected, NULL); /* handle the keys */ - if (ui_menu_generic_keys(&selected, menu_items, visible_items)) + if (ui_menu_generic_keys(machine, &selected, menu_items, visible_items)) return selected; /* handle actions */ - if (input_ui_pressed(IPT_UI_SELECT)) + if (input_ui_pressed(machine, IPT_UI_SELECT)) { if (selected == menu_items - 2) { @@ -1478,11 +1520,11 @@ static UINT32 menu_video(UINT32 state) visible_items = ui_menu_draw(item_list, menu_items, selected, NULL); /* handle the keys */ - if (ui_menu_generic_keys(&selected, menu_items, visible_items)) + if (ui_menu_generic_keys(machine, &selected, menu_items, visible_items)) return selected; /* handle actions */ - if (input_ui_pressed(IPT_UI_SELECT)) + if (input_ui_pressed(machine, IPT_UI_SELECT)) { /* rotate */ if (selected == menu_items - 6) @@ -1535,10 +1577,10 @@ static UINT32 menu_video(UINT32 state) quitting the game -------------------------------------------------*/ -static UINT32 menu_quit_game(UINT32 state) +static UINT32 menu_quit_game(running_machine *machine, UINT32 state) { /* request a reset */ - mame_schedule_exit(Machine); + mame_schedule_exit(machine); /* reset the menu stack */ ui_menu_stack_reset(); @@ -1551,7 +1593,7 @@ static UINT32 menu_quit_game(UINT32 state) menu -------------------------------------------------*/ -static UINT32 menu_select_game(UINT32 state) +static UINT32 menu_select_game(running_machine *machine, UINT32 state) { ui_menu_item item_list[VISIBLE_GAMES_IN_LIST + 2]; int error = (state >> 17) & 1; @@ -1649,7 +1691,7 @@ static UINT32 menu_select_game(UINT32 state) recompute |= select_game_handle_key(curkey, curkey - KEYCODE_0_PAD + '0'); /* escape pressed with non-empty text clears the text */ - if (input_ui_pressed(IPT_UI_CANCEL)) + if (input_ui_pressed(machine, IPT_UI_CANCEL)) { if (select_game_buffer[0] == 0) return ui_menu_stack_pop(); @@ -1665,14 +1707,14 @@ static UINT32 menu_select_game(UINT32 state) selected = 0; /* ignore pause keys by swallowing them */ - input_ui_pressed(IPT_UI_PAUSE); + input_ui_pressed(machine, IPT_UI_PAUSE); /* handle the generic keys */ - if (!recompute && ui_menu_generic_keys(&selected, menu_items, visible_items)) + if (!recompute && ui_menu_generic_keys(machine, &selected, menu_items, visible_items)) return selected; /* handle actions */ - if (input_ui_pressed(IPT_UI_SELECT)) + if (input_ui_pressed(machine, IPT_UI_SELECT)) { /* control config */ if (ui_menu_is_force_game_select() && selected == menu_items - 2) @@ -1694,7 +1736,7 @@ static UINT32 menu_select_game(UINT32 state) /* if everything looks good, schedule the new driver */ if (audit_result == CORRECT || audit_result == BEST_AVAILABLE) { - mame_schedule_new_driver(Machine, select_game_list[selected]); + mame_schedule_new_driver(machine, select_game_list[selected]); ui_menu_stack_reset(); return 0; } @@ -1718,7 +1760,7 @@ static UINT32 menu_select_game(UINT32 state) -------------------------------------------------*/ #ifdef MESS -static UINT32 menu_file_manager(UINT32 state) +static UINT32 menu_file_manager(running_machine *machine, UINT32 state) { int result = filemanager(state); if (result == 0) @@ -1734,7 +1776,7 @@ static UINT32 menu_file_manager(UINT32 state) #ifdef MESS #if HAS_WAVE -static UINT32 menu_tape_control(UINT32 state) +static UINT32 menu_tape_control(running_machine *machine, UINT32 state) { int result = tapecontrol(state); if (result == 0) @@ -1810,55 +1852,56 @@ static void menu_render_triangle(bitmap_t *dest, const bitmap_t *source, const r for a given group of inputs -------------------------------------------------*/ -static int input_menu_get_items(input_item_data *itemlist, int group) +static int input_menu_get_items(running_machine *machine, input_item_data *itemlist, int group) { input_item_data *item = itemlist; - const input_port_default_entry *indef; - input_port_default_entry *in; + const input_type_desc *typedesc; astring *seqstring; - /* an out of range group is special; it just means the game-specific inputs */ - if (group > IPG_TOTAL_GROUPS) - return input_menu_get_game_items(itemlist); - /* iterate over the input ports and add menu items */ seqstring = astring_alloc(); - for (in = get_input_port_list(), indef = get_input_port_list_defaults(); in->type != IPT_END; in++, indef++) + for (typedesc = input_type_list(machine); typedesc != NULL; typedesc = typedesc->next) /* add if we match the group and we have a valid name */ - if (in->group == group && in->name && in->name[0] != 0) + if (typedesc->group == group && typedesc->name != NULL && typedesc->name[0] != 0) { /* build an entry for the standard sequence */ - item->seq = &in->defaultseq; - item->defseq = &indef->defaultseq; + item->typedesc = typedesc; + item->seqtype = SEQ_TYPE_STANDARD; + item->seq = *input_type_seq(machine, typedesc->type, typedesc->player, item->seqtype); + item->defseq = &typedesc->seq[item->seqtype]; item->sortorder = item - itemlist; - item->type = port_type_is_analog(in->type) ? INPUT_TYPE_ANALOG : INPUT_TYPE_DIGITAL; - item->name = menu_string_pool_add(input_format[item->type], in->name); - item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, item->seq))); - item->invert = input_seq_cmp(item->seq, item->defseq); + item->type = input_type_is_analog(typedesc->type) ? INPUT_TYPE_ANALOG : INPUT_TYPE_DIGITAL; + item->name = menu_string_pool_add(input_format[item->type], typedesc->name); + item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, &item->seq))); + item->invert = input_seq_cmp(&item->seq, item->defseq); item++; /* if we're analog, add more entries */ if (item[-1].type == INPUT_TYPE_ANALOG) { /* build an entry for the decrement sequence */ - item->seq = &in->defaultdecseq; - item->defseq = &indef->defaultdecseq; + item->typedesc = typedesc; + item->seqtype = SEQ_TYPE_DECREMENT; + item->seq = *input_type_seq(machine, typedesc->type, typedesc->player, item->seqtype); + item->defseq = &typedesc->seq[item->seqtype]; item->sortorder = item - itemlist; item->type = INPUT_TYPE_ANALOG_DEC; - item->name = menu_string_pool_add(input_format[item->type], in->name); - item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, item->seq))); - item->invert = input_seq_cmp(item->seq, item->defseq); + item->name = menu_string_pool_add(input_format[item->type], typedesc->name); + item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, &item->seq))); + item->invert = input_seq_cmp(&item->seq, item->defseq); item++; /* build an entry for the increment sequence */ - item->seq = &in->defaultincseq; - item->defseq = &indef->defaultincseq; + item->typedesc = typedesc; + item->seqtype = SEQ_TYPE_INCREMENT; + item->seq = *input_type_seq(machine, typedesc->type, typedesc->player, item->seqtype); + item->defseq = &typedesc->seq[item->seqtype]; item->sortorder = item - itemlist; item->type = INPUT_TYPE_ANALOG_INC; - item->name = menu_string_pool_add(input_format[item->type], in->name); - item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, item->seq))); - item->invert = input_seq_cmp(item->seq, item->defseq); + item->name = menu_string_pool_add(input_format[item->type], typedesc->name); + item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, &item->seq))); + item->invert = input_seq_cmp(&item->seq, item->defseq); item++; } } @@ -1870,85 +1913,93 @@ static int input_menu_get_items(input_item_data *itemlist, int group) /*------------------------------------------------- + get_field_default_seq - return a pointer + to the default sequence for the given field +-------------------------------------------------*/ + +static const input_seq *get_field_default_seq(const input_field_config *field, int seqtype) +{ + if (input_seq_get_1(&field->seq[seqtype]) == SEQCODE_DEFAULT) + return input_type_seq(field->port->machine, field->type, field->player, seqtype); + else + return &field->seq[seqtype]; +} + + +/*------------------------------------------------- input_menu_get_game_items - build a list of items for the game-specific inputs -------------------------------------------------*/ -static int input_menu_get_game_items(input_item_data *itemlist) +static int input_menu_get_game_items(running_machine *machine, input_item_data *itemlist) { - static const input_seq default_seq = SEQ_DEF_1(SEQCODE_DEFAULT); astring *seqstring = astring_alloc(); input_item_data *item = itemlist; - input_port_entry *in; + const input_port_config *port; + const input_field_config *field; /* iterate over the input ports and add menu items */ - for (in = Machine->input_ports; in->type != IPT_END; in++) - { - const char *name = input_port_name(in); + for (port = machine->portconfig; port != NULL; port = port->next) + for (field = port->fieldlist; field != NULL; field = field->next) + { + const char *name = input_field_name(field); - /* add if we match the group and we have a valid name */ - if ((name != NULL) && (input_port_condition(in)) && + /* add if we match the group and we have a valid name */ + if (name != NULL && input_condition_true(machine, &field->condition) && #ifdef MESS - (in->category == 0 || input_category_active(Machine, in->category)) && + (field->category == 0 || input_category_active(machine, field->category)) && #endif /* MESS */ - ((in->type == IPT_OTHER && in->name != IP_NAME_DEFAULT) || port_type_to_group(in->type, in->player) != IPG_INVALID)) - { - UINT16 sortorder; - const input_seq *curseq, *defseq; - - /* determine the sorting order */ - if (in->type >= IPT_START1 && in->type <= __ipt_analog_end) - sortorder = (in->type << 2) | (in->player << 12); - else - sortorder = in->type | 0xf000; - - /* fetch data for the standard sequence */ - curseq = input_port_seq(in, SEQ_TYPE_STANDARD); - defseq = input_port_default_seq(in->type, in->player, SEQ_TYPE_STANDARD); - - /* build an entry for the standard sequence */ - item->seq = &in->seq; - item->defseq = &default_seq; - item->sortorder = sortorder; - item->type = port_type_is_analog(in->type) ? INPUT_TYPE_ANALOG : INPUT_TYPE_DIGITAL; - item->name = menu_string_pool_add(input_format[item->type], name); - item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, curseq))); - item->invert = input_seq_cmp(curseq, defseq); - item++; - - /* if we're analog, add more entries */ - if (item[-1].type == INPUT_TYPE_ANALOG) + ((field->type == IPT_OTHER && field->name != NULL) || input_type_group(machine, field->type, field->player) != IPG_INVALID)) { - /* fetch data for the decrement sequence */ - curseq = input_port_seq(in, SEQ_TYPE_DECREMENT); - defseq = input_port_default_seq(in->type, in->player, SEQ_TYPE_DECREMENT); - - /* build an entry for the decrement sequence */ - item->seq = &in->analog.decseq; - item->defseq = &default_seq; - item->sortorder = sortorder; - item->type = INPUT_TYPE_ANALOG_DEC; - item->name = menu_string_pool_add(input_format[item->type], name); - item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, curseq))); - item->invert = input_seq_cmp(curseq, defseq); - item++; + UINT16 sortorder; - /* fetch data for the increment sequence */ - curseq = input_port_seq(in, SEQ_TYPE_INCREMENT); - defseq = input_port_default_seq(in->type, in->player, SEQ_TYPE_INCREMENT); + /* determine the sorting order */ + if (field->type >= IPT_START1 && field->type <= __ipt_analog_end) + sortorder = (field->type << 2) | (field->player << 12); + else + sortorder = field->type | 0xf000; - /* build an entry for the increment sequence */ - item->seq = &in->analog.incseq; - item->defseq = &default_seq; + /* build an entry for the standard sequence */ + item->field = field; + item->seqtype = SEQ_TYPE_STANDARD; + item->seq = *input_field_seq(field, item->seqtype); + item->defseq = get_field_default_seq(field, item->seqtype); item->sortorder = sortorder; - item->type = INPUT_TYPE_ANALOG_INC; + item->type = input_type_is_analog(field->type) ? INPUT_TYPE_ANALOG : INPUT_TYPE_DIGITAL; item->name = menu_string_pool_add(input_format[item->type], name); - item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, curseq))); - item->invert = input_seq_cmp(curseq, defseq); + item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, &item->seq))); + item->invert = input_seq_cmp(&item->seq, item->defseq); item++; + + /* if we're analog, add more entries */ + if (item[-1].type == INPUT_TYPE_ANALOG) + { + /* build an entry for the decrement sequence */ + item->field = field; + item->seqtype = SEQ_TYPE_DECREMENT; + item->seq = *input_field_seq(field, item->seqtype); + item->defseq = get_field_default_seq(field, item->seqtype); + item->sortorder = sortorder; + item->type = INPUT_TYPE_ANALOG_DEC; + item->name = menu_string_pool_add(input_format[item->type], name); + item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, &item->seq))); + item->invert = input_seq_cmp(&item->seq, item->defseq); + item++; + + /* build an entry for the increment sequence */ + item->field = field; + item->seqtype = SEQ_TYPE_INCREMENT; + item->seq = *input_field_seq(field, item->seqtype); + item->defseq = get_field_default_seq(field, item->seqtype); + item->sortorder = sortorder; + item->type = INPUT_TYPE_ANALOG_INC; + item->name = menu_string_pool_add(input_format[item->type], name); + item->seqname = menu_string_pool_add("%s", astring_c(input_seq_name(seqstring, &item->seq))); + item->invert = input_seq_cmp(&item->seq, item->defseq); + item++; + } } } - } /* return the number of items */ astring_free(seqstring); @@ -2001,24 +2052,26 @@ static int input_menu_compare_items(const void *i1, const void *i2) switches menu list -------------------------------------------------*/ -static void switches_menu_add_item(ui_menu_item *item, const input_port_entry *in, int switch_entry, void *ref) +static void switches_menu_add_item(ui_menu_item *item, const input_field_config *field) { - const input_port_entry *tin; + const input_setting_config *setting; + input_field_user_settings settings; /* set the text to the name and the subitem text to invalid */ - item->text = input_port_name(in); + input_field_get_user_settings(field, &settings); + item->text = input_field_name(field); item->subtext = NULL; /* scan for the current selection in the list */ - for (tin = in + 1; tin->type == switch_entry; tin++) - if (input_port_condition(tin)) + for (setting = field->settinglist; setting != NULL; setting = setting->next) + if (input_condition_true(field->port->machine, &setting->condition)) { /* if this is a match, set the subtext */ - if (in->default_value == tin->default_value) - item->subtext = input_port_name(tin); + if (setting->value == settings.value) + item->subtext = setting->name; /* else if we haven't seen a match yet, show a left arrow */ - else if (!item->subtext) + else if (item->subtext == NULL) item->flags |= MENU_FLAG_LEFT_ARROW; /* else if we have seen a match, show a right arrow */ @@ -2027,11 +2080,11 @@ static void switches_menu_add_item(ui_menu_item *item, const input_port_entry *i } /* if no matches, we're invalid */ - if (!item->subtext) + if (item->subtext == NULL) item->subtext = "INVALID"; /* stash our reference */ - item->ref = ref; + item->ref = (void *)field; } @@ -2040,26 +2093,41 @@ static void switches_menu_add_item(ui_menu_item *item, const input_port_entry *i previous item in the switches list -------------------------------------------------*/ -static void switches_menu_select_previous(input_port_entry *in, int switch_entry) +static void switches_menu_select_previous(const input_field_config *field) { - int last_value = in->default_value; - const input_port_entry *tin; - - /* scan for the current selection in the list */ - for (tin = in + 1; tin->type == switch_entry; tin++) - if (input_port_condition(tin)) + const input_setting_config *setting, *prevsetting; + input_field_user_settings settings; + int found_match = FALSE; + + /* get the current configured settings */ + input_field_get_user_settings(field, &settings); + + /* scan the list of settings looking for a match on the current value */ + prevsetting = NULL; + for (setting = field->settinglist; setting != NULL; setting = setting->next) + { + if (setting->value == settings.value) { - /* if this is a match, we're done */ - if (in->default_value == tin->default_value) - { - in->default_value = last_value; - return; - } - - /* otherwise, keep track of last one found */ - else - last_value = tin->default_value; + found_match = TRUE; + if (prevsetting != NULL) + break; } + if (input_condition_true(field->port->machine, &setting->condition)) + prevsetting = setting; + } + + /* if we didn't find a matching value, select the first */ + if (!found_match) + { + for (prevsetting = field->settinglist; prevsetting != NULL; prevsetting = prevsetting->next) + if (input_condition_true(field->port->machine, &prevsetting->condition)) + break; + } + + /* update the value to the previous one */ + if (prevsetting != NULL) + settings.value = prevsetting->value; + input_field_set_user_settings(field, &settings); } @@ -2068,44 +2136,37 @@ static void switches_menu_select_previous(input_port_entry *in, int switch_entry next item in the switches list -------------------------------------------------*/ -static void switches_menu_select_next(input_port_entry *in, int switch_entry) -{ - const input_port_entry *tin; - int foundit = FALSE; - - /* scan for the current selection in the list */ - for (tin = in + 1; tin->type == switch_entry; tin++) - if (input_port_condition(tin)) - { - /* if we found the current selection, we pick the next one */ - if (foundit) - { - in->default_value = tin->default_value; - return; - } - - /* if this is a match, note it */ - if (in->default_value == tin->default_value) - foundit = TRUE; - } -} - - -/*------------------------------------------------- - switches_menu_compare_items - compare two - switches items for quicksort purposes --------------------------------------------------*/ - -/* -static int switches_menu_compare_items(const void *i1, const void *i2) +static void switches_menu_select_next(const input_field_config *field) { - const ui_menu_item *item1 = i1; - const ui_menu_item *item2 = i2; - const input_port_entry *data1 = item1->ref; - const input_port_entry *data2 = item2->ref; - return strcmp(input_port_name(data1), input_port_name(data2)); + const input_setting_config *setting, *nextsetting; + input_field_user_settings settings; + + /* get the current configured settings */ + input_field_get_user_settings(field, &settings); + + /* scan the list of settings looking for a match on the current value */ + nextsetting = NULL; + for (setting = field->settinglist; setting != NULL; setting = setting->next) + if (setting->value == settings.value) + break; + + /* if we found one, scan forward for the next valid one */ + if (setting != NULL) + for (nextsetting = setting->next; nextsetting != NULL; nextsetting = nextsetting->next) + if (input_condition_true(field->port->machine, &nextsetting->condition)) + break; + + /* if we hit the end, search from the beginning */ + if (nextsetting == NULL) + for (nextsetting = field->settinglist; nextsetting != NULL; nextsetting = nextsetting->next) + if (input_condition_true(field->port->machine, &nextsetting->condition)) + break; + + /* update the value to the previous one */ + if (nextsetting != NULL) + settings.value = nextsetting->value; + input_field_set_user_settings(field, &settings); } -*/ /*------------------------------------------------- @@ -2113,40 +2174,43 @@ static int switches_menu_compare_items(const void *i1, const void *i2) analog controls menu -------------------------------------------------*/ -static void analog_menu_add_item(ui_menu_item *item, const input_port_entry *in, const char *append_string, int which_item) +static void analog_menu_add_item(ui_menu_item *item, const input_field_config *field, const char *append_string, int which_item) { + input_field_user_settings settings; int value, minval, maxval; + input_field_get_user_settings(field, &settings); + /* set the item text using the formatting string provided */ - item->text = menu_string_pool_add("%s %s", input_port_name(in), append_string); + item->text = menu_string_pool_add("%s %s", input_field_name(field), append_string); /* set the subitem text */ switch (which_item) { default: case ANALOG_ITEM_KEYSPEED: - value = in->analog.delta; + value = settings.delta; minval = 0; maxval = 255; item->subtext = menu_string_pool_add("%d", value); break; case ANALOG_ITEM_CENTERSPEED: - value = in->analog.centerdelta; + value = settings.centerdelta; minval = 0; maxval = 255; item->subtext = menu_string_pool_add("%d", value); break; case ANALOG_ITEM_REVERSE: - value = in->analog.reverse; + value = settings.reverse; minval = 0; maxval = 1; item->subtext = value ? "On" : "Off"; break; case ANALOG_ITEM_SENSITIVITY: - value = in->analog.sensitivity; + value = settings.sensitivity; minval = 1; maxval = 255; item->subtext = menu_string_pool_add("%d%%", value); @@ -2166,40 +2230,44 @@ static void analog_menu_add_item(ui_menu_item *item, const input_port_entry *in, for DIP switches -------------------------------------------------*/ -static void dip_switch_build_model(input_port_entry *entry, int item_is_selected) +static void dip_switch_build_model(const input_field_config *field, int item_is_selected) { - int dip_declaration_index = 0; - int value_mask_temp = entry->mask; + input_port_value value_mask_temp = field->mask; + const input_field_diplocation *diploc; + input_port_value toggle_switch_mask; + input_field_user_settings settings; int value_mask_bit = 0; - int toggle_switch_mask; - int model_index = 0; + int model_index; int toggle_num; - if (entry->diploc[dip_declaration_index].swname == NULL) + diploc = field->diploclist; + if (diploc == NULL || diploc->swname == NULL) return; + + input_field_get_user_settings(field, &settings); /* get the entry in the model to work with */ - do + for (model_index = 0; model_index < MAX_PHYSICAL_DIPS; model_index++) { /* use this entry if it's not used */ if (dip_switch_model[model_index].dip_name == NULL) { - dip_switch_model[model_index].dip_name = entry->diploc[dip_declaration_index].swname; + dip_switch_model[model_index].dip_name = diploc->swname; break; } /* reuse this entry if the switch name matches */ - if (!strcmp(entry->diploc[dip_declaration_index].swname, dip_switch_model[model_index].dip_name)) + if (!strcmp(diploc->swname, dip_switch_model[model_index].dip_name)) break; // todo: add a check here to see if we go over the max dips and throw an error. - } while (++model_index < MAX_PHYSICAL_DIPS); + } /* Create a mask depicting the number of toggles on the physical switch */ - while (entry->diploc[dip_declaration_index].swname) + for ( ; diploc != NULL; diploc = diploc->next) { /* get the Nth DIP toggle number */ - toggle_num = entry->diploc[dip_declaration_index].swnum; + toggle_num = diploc->swnum; /* get the Nth mask bit - * should probably put a check here to avoid bad driver definitions @@ -2218,18 +2286,16 @@ static void dip_switch_build_model(input_port_entry *entry, int item_is_selected dip_switch_model[model_index].total_dip_mask |= toggle_switch_mask; /* if it's inverted, mark it as such */ - if (entry->diploc[dip_declaration_index].invert) + if (diploc->invert) dip_switch_model[model_index].dip_invert_mask |= toggle_switch_mask; /* if isolated bit is on, set the toggle on */ - if ((1 << value_mask_bit) & entry->default_value) + if ((1 << value_mask_bit) & settings.value) dip_switch_model[model_index].total_dip_settings |= toggle_switch_mask; /* indicate if the toggle is selected */ if (item_is_selected) dip_switch_model[model_index].selected_dip_feature_mask |= toggle_switch_mask; - - ++dip_declaration_index; } } |