/** * This function is called back by MAME when it is starting up. It passes the * descriptor that it uses internally for every possible input port, and gives * us the opportunity to define what callback we will provide for fetching the * state of that input port. We ignore those input ports that are not used in * the current game, and for the others, make our own custom controllers as * neceessary to provide the inputs, and hook the input callbacks up to fetch * the input state from the one single LibMame_AllControlsState structure * that we store in the g_state object. In this way, we completely hardwire * the way that MAME handles input so that the users of libmame can do * whatever they want to satisfy getting inputs for the various controllers * types. **/ static void osd_customize_input_type_list(input_type_desc *typelist) { /** * For each input descriptor, create a keyboard key, or mouse axis, or * lightgun control, or joystick axis for it, and change its input * sequence to match the new item. Also, set up the polling callback for * it to have the data it needs to get the right controller state. **/ input_type_desc *typedesc; input_device *item_device; input_item_id item_id = ITEM_ID_INVALID; int input_code = 0; /** * New keyboards are created as we run out of keys; the only keys we * use are between ITEM_ID_A and ITEM_ID_Z (inclusive). It is * important that ITEM_IDs that identify keys from a keyboard are used as * MAME internally detects the ITEM_ID type and treats it specially in * different circumstances, and so the ITEM_ID must "match" the * input_device type that it is attached to. For example, if we used * something outside of the key range for a keyboard * (e.g. ITEM_ID_RELATIVE1), then MAME would interpret the INT32 that it * gets when it calls back to get the state of the input incorrectly (it * would interpret it as some kind of delta value, not as a "pressed or * not pressed" boolean). The same concept holds true for joysticks, * mice, etc, so those only use ITEM_ID values that make sense for their * types. And why only use keyboard keys up to Z and not the others? * Well, apparently MAME also does something very weird and interprets * devices which have been mapped to key '0' (and probably other MAME * default UI keys) as having input that triggers that UI event. **/ input_device *keyboard = 0; input_item_id keyboard_item = ITEM_ID_A; int keyboard_count = 0; /* As to all of the rest, they are created as needed, one for each player */ input_device *analog_joystick[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; input_device *spinner[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; input_device *paddle[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; input_device *trackball[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; input_device *lightgun[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; input_device *pedal[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; char namebuf[256]; #define GET_ITEM_DEVICE_AND_ID(device_type, device_class, item_class) \ do { \ if (device_type [typedesc->player] == 0) { \ snprintf(namebuf, sizeof(namebuf), \ "libmame_virtual_" #device_type "_%d", \ typedesc->player); \ device_type [typedesc->player] = input_device_add \ (g_state.machine, device_class, namebuf, NULL); \ } \ item_device = device_type [typedesc->player]; \ item_id = g_input_descriptors[typedesc->type].item_id; \ input_code = INPUT_CODE(device_class, \ input_device_get_index \ (g_state.machine, \ device_type [typedesc->player]), \ item_class, ITEM_MODIFIER_NONE, \ item_id); \ } while (0); for (typedesc = typelist; typedesc; typedesc = typedesc->next) { item_device = NULL; if (controllers_have_input(g_state.maximum_player_count, &(g_state.controllers), typedesc->player, typedesc->type)) { switch (g_input_descriptors[typedesc->type].type) { case libmame_input_type_invalid: break; case libmame_input_type_Normal_button: case libmame_input_type_Mahjong_button: case libmame_input_type_Hanafuda_button: case libmame_input_type_Gambling_button: case libmame_input_type_Shared_button: case libmame_input_type_left_joystick: case libmame_input_type_right_joystick: case libmame_input_type_Ui_button: if (!keyboard || (keyboard_item > ITEM_ID_Z)) { snprintf(namebuf, sizeof(namebuf), "libmame_virtual_keyboard_%d", keyboard_count++); keyboard = input_device_add (g_state.machine, DEVICE_CLASS_KEYBOARD, namebuf, NULL); keyboard_item = ITEM_ID_A; } item_device = keyboard; item_id = keyboard_item; keyboard_item++; input_code = INPUT_CODE(DEVICE_CLASS_KEYBOARD, input_device_get_index(g_state.machine, keyboard), ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, item_id); break; /* * For all of the following, we use DEVICE_CLASS_LIGHTGUN, * ITEM_CLASS_ABSOLUTE for any device for which we provide * absolute values, and DEVICE_CLASS_MOUSE, * ITEM_CLASS_RELATIVE for any device for which we provide * relative values. The { MOUSE, RELATIVE } choice makes * sense, but the { LIGHTGUN, ABSOLUTE } seems weird for * things like analog joysticks and paddles. However, * LIGHTGUN is the device class that MAME does the least * amount of internal fiddling with when interpreting input * values, and that's what we want. If we choose * DEVICE_CLASS_JOYSTICK then it will do deadzone stuff, and * if we choose DEVICE_CLASS_MOUSE, it will force the input to * be relative which will cause input handling to always use * 0. It's weird, but DEVICE_CLASS_LIGHTGUN is the best * choice for any absolute control type. */ case libmame_input_type_analog_joystick_horizontal: case libmame_input_type_analog_joystick_vertical: /* Yes, it's weird that LIGHTGUN is used here - see above comment */ GET_ITEM_DEVICE_AND_ID(analog_joystick, DEVICE_CLASS_LIGHTGUN, ITEM_CLASS_ABSOLUTE); break; case libmame_input_type_spinner: case libmame_input_type_vertical_spinner: GET_ITEM_DEVICE_AND_ID(spinner, DEVICE_CLASS_MOUSE, ITEM_CLASS_RELATIVE); break; case libmame_input_type_paddle: case libmame_input_type_vertical_paddle: /* Yes, it's weird that LIGHTGUN is used here - see above comment */ GET_ITEM_DEVICE_AND_ID(paddle, DEVICE_CLASS_LIGHTGUN, ITEM_CLASS_ABSOLUTE); break; case libmame_input_type_trackball_horizontal: case libmame_input_type_trackball_vertical: GET_ITEM_DEVICE_AND_ID(trackball, DEVICE_CLASS_MOUSE, ITEM_CLASS_RELATIVE); break; case libmame_input_type_lightgun_horizontal: case libmame_input_type_lightgun_vertical: /* Hey, LIGHTGUN actually makes sense here! */ GET_ITEM_DEVICE_AND_ID(lightgun, DEVICE_CLASS_LIGHTGUN, ITEM_CLASS_ABSOLUTE); break; case libmame_input_type_pedal: case libmame_input_type_pedal2: case libmame_input_type_pedal3: /* Yes, it's weird that LIGHTGUN is used here - see above comment */ GET_ITEM_DEVICE_AND_ID(pedal, DEVICE_CLASS_LIGHTGUN, ITEM_CLASS_ABSOLUTE); break; } } if (item_device) { input_device_item_add (item_device, "", (void *) CBDATA_MAKE(typedesc->player, typedesc->type), item_id, &get_controller_state); } else { /* For some reason or another, we can't handle this input, so turn it off by setting it to an item_id that we never use */ item_id = ITEM_ID_MAXIMUM; } input_seq_set_1(&(typedesc->seq[SEQ_TYPE_STANDARD]), input_code); } }
void osd_customize_input_type_list(input_type_desc *typelist) { input_type_desc *typedesc; for (typedesc = typelist; typedesc != NULL; typedesc = typedesc->next) { switch (typedesc->type) { case IPT_UI_UP: case IPT_UI_DOWN: case IPT_UI_LEFT: case IPT_UI_RIGHT: case IPT_UI_CANCEL: case IPT_UI_PAGE_UP: case IPT_UI_PAGE_DOWN: continue; } if(typedesc->type >= __ipt_ui_start && typedesc->type <= __ipt_ui_end) input_seq_set_0(&typedesc->seq[SEQ_TYPE_STANDARD]); if(typedesc->type >= IPT_MAHJONG_A && typedesc->type <= IPT_SLOT_STOP_ALL) input_seq_set_0(&typedesc->seq[SEQ_TYPE_STANDARD]); } for (typedesc = typelist; typedesc != NULL; typedesc = typedesc->next) { switch (typedesc->type) { case IPT_UI_CONFIGURE: input_seq_set_2(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 0), INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 0)); break; case IPT_COIN1: input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 0)); break; case IPT_START1: input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 0)); break; case IPT_COIN2: input_seq_set_5(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 0), INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1UP),0),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 0), INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 0)); input_seq_append_or(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 1)); break; case IPT_START2: input_seq_set_5(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 0), STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1UP),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 0), INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 0)); input_seq_append_or(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 1)); break; case IPT_COIN3: input_seq_set_5(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 0), INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1RIGHT),0),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 0), INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 0)); input_seq_append_or(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 2)); break; case IPT_START3: input_seq_set_5(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 0), STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1RIGHT),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 0), INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 0)); input_seq_append_or(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 2)); break; case IPT_COIN4: input_seq_set_5(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 0), INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1DOWN),0),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 0), INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 0)); input_seq_append_or(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON7, 3)); break; case IPT_START4: input_seq_set_5(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 0), STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1DOWN),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 0), INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 0)); input_seq_append_or(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON8, 3)); break; case IPT_UI_LOAD_STATE: input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], KEYCODE_F7); break; case IPT_UI_SAVE_STATE: input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], KEYCODE_F8); break; case IPT_UI_SELECT: input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON1, 0)); break; case IPT_UI_UP: input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1UP), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 0)); break; case IPT_UI_DOWN: input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1DOWN), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 0)); break; case IPT_UI_LEFT: input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1LEFT), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_LEFT_SWITCH, 0)); break; case IPT_UI_RIGHT: input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1RIGHT), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 0)); break; case IPT_OSD_1: input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON2, 0)); break; case IPT_JOYSTICK_UP: case IPT_JOYSTICKLEFT_UP: if(typedesc->group == IPG_PLAYER1) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1UP), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 0)); else if(typedesc->group == IPG_PLAYER2) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2UP),1), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 1)); else if(typedesc->group == IPG_PLAYER3) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3UP),2), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 2)); else if(typedesc->group == IPG_PLAYER4) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4UP),3), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 3)); break; case IPT_JOYSTICK_DOWN: case IPT_JOYSTICKLEFT_DOWN: if(typedesc->group == IPG_PLAYER1) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1DOWN), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 0)); else if(typedesc->group == IPG_PLAYER2) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2DOWN),1), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 1)); else if(typedesc->group == IPG_PLAYER3) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3DOWN),2), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 2)); else if(typedesc->group == IPG_PLAYER4) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4DOWN),3), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 3)); break; case IPT_JOYSTICK_LEFT: case IPT_JOYSTICKLEFT_LEFT: if(typedesc->group == IPG_PLAYER1) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1LEFT), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_LEFT_SWITCH, 0)); else if(typedesc->group == IPG_PLAYER2) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2LEFT),1), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_LEFT_SWITCH, 1)); else if(typedesc->group == IPG_PLAYER3) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3LEFT),2), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_LEFT_SWITCH, 2)); else if(typedesc->group == IPG_PLAYER4) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4LEFT),3), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_LEFT_SWITCH, 3)); break; case IPT_JOYSTICK_RIGHT: case IPT_JOYSTICKLEFT_RIGHT: if(typedesc->group == IPG_PLAYER1) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1RIGHT), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 0)); else if(typedesc->group == IPG_PLAYER2) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2RIGHT),1), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 1)); else if(typedesc->group == IPG_PLAYER3) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3RIGHT),2), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 2)); else if(typedesc->group == IPG_PLAYER4) input_seq_set_3(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4RIGHT),3), SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 3)); break; case IPT_POSITIONAL: if(typedesc->group == IPG_PLAYER1) { input_seq_set_0(&typedesc->seq[SEQ_TYPE_STANDARD]); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON5, 0)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON6, 0)); } else if(typedesc->group == IPG_PLAYER2) { input_seq_set_0(&typedesc->seq[SEQ_TYPE_STANDARD]); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON5, 1)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON6, 1)); } else if(typedesc->group == IPG_PLAYER3) { input_seq_set_0(&typedesc->seq[SEQ_TYPE_STANDARD]); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON5, 2)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON6, 2)); } else if(typedesc->group == IPG_PLAYER4) { input_seq_set_0(&typedesc->seq[SEQ_TYPE_STANDARD]); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON5, 3)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON6, 3)); } break; case IPT_PADDLE: case IPT_TRACKBALL_X: case IPT_AD_STICK_X: case IPT_LIGHTGUN_X: case IPT_DIAL: if(typedesc->group == IPG_PLAYER1) { input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_X,0)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1LEFT),0)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1RIGHT),0)); } else if(typedesc->group == IPG_PLAYER2) { input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_X,1)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2LEFT),1)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2RIGHT),1)); } else if(typedesc->group == IPG_PLAYER3) { input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_X,2)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3LEFT),2)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3RIGHT),2)); } else if(typedesc->group == IPG_PLAYER4) { input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_X,3)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4LEFT),3)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4RIGHT),3)); } break; case IPT_PADDLE_V: case IPT_TRACKBALL_Y: case IPT_AD_STICK_Y: case IPT_LIGHTGUN_Y: case IPT_POSITIONAL_V: case IPT_DIAL_V: if(typedesc->group == IPG_PLAYER1) { input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_Y,0)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1UP),0)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1DOWN),0)); } else if(typedesc->group == IPG_PLAYER2) { input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_Y,1)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2UP),1)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2DOWN),1)); } else if(typedesc->group == IPG_PLAYER3) { input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_Y,2)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3UP),2)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3DOWN),2)); } else if(typedesc->group == IPG_PLAYER4) { input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD],INPUT_CODE_SET_DEVINDEX(JOYCODE_Y,3)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4UP),3)); input_seq_set_1(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4DOWN),3)); } break; case IPT_MOUSE_X: if(typedesc->group == IPG_PLAYER1) { input_seq_set_3(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1LEFT),0),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_LEFT_SWITCH, 0)); input_seq_set_3(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1RIGHT),0),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 0)); } else if(typedesc->group == IPG_PLAYER2) { input_seq_set_3(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2LEFT),1),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_LEFT_SWITCH, 1)); input_seq_set_3(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2RIGHT),1),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 1)); } else if(typedesc->group == IPG_PLAYER3) { input_seq_set_3(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3LEFT),2),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_LEFT_SWITCH, 2)); input_seq_set_3(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3RIGHT),2),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 2)); } else if(typedesc->group == IPG_PLAYER4) { input_seq_set_3(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4LEFT),3),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_LEFT_SWITCH, 3)); input_seq_set_3(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4RIGHT),3),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_X_RIGHT_SWITCH, 3)); } break; case IPT_MOUSE_Y: if(typedesc->group == IPG_PLAYER1) { input_seq_set_3(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1UP),0),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 0)); input_seq_set_3(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT1DOWN),0),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 0)); } else if(typedesc->group == IPG_PLAYER2) { input_seq_set_3(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2UP),1),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 1)); input_seq_set_3(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT2DOWN),1),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 1)); } else if(typedesc->group == IPG_PLAYER3) { input_seq_set_3(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3UP),2),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 2)); input_seq_set_3(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT3DOWN),2),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 2)); } else if(typedesc->group == IPG_PLAYER4) { input_seq_set_3(&typedesc->seq[SEQ_TYPE_DECREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4UP),3),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_UP_SWITCH, 3)); input_seq_set_3(&typedesc->seq[SEQ_TYPE_INCREMENT],INPUT_CODE_SET_DEVINDEX(STANDARD_CODE(JOYSTICK, 0, SWITCH, NONE, HAT4DOWN),3),SEQCODE_OR, INPUT_CODE_SET_DEVINDEX(JOYCODE_Y_DOWN_SWITCH, 3)); } break; case IPT_JOYSTICKRIGHT_UP: if(typedesc->group == IPG_PLAYER1) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON4, 0)); else if(typedesc->group == IPG_PLAYER2) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON4, 1)); else if(typedesc->group == IPG_PLAYER3) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON4, 2)); else if(typedesc->group == IPG_PLAYER4) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON4, 3)); break; case IPT_JOYSTICKRIGHT_DOWN: if(typedesc->group == IPG_PLAYER1) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON2, 0)); else if(typedesc->group == IPG_PLAYER2) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON2, 1)); else if(typedesc->group == IPG_PLAYER3) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON2, 2)); else if(typedesc->group == IPG_PLAYER4) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON2, 3)); break; case IPT_JOYSTICKRIGHT_LEFT: if(typedesc->group == IPG_PLAYER1) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON3, 0)); else if(typedesc->group == IPG_PLAYER2) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON3, 1)); else if(typedesc->group == IPG_PLAYER3) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON3, 2)); else if(typedesc->group == IPG_PLAYER4) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON3, 3)); break; case IPT_JOYSTICKRIGHT_RIGHT: if(typedesc->group == IPG_PLAYER1) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON1, 0)); else if(typedesc->group == IPG_PLAYER2) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON1, 1)); else if(typedesc->group == IPG_PLAYER3) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON1, 2)); else if(typedesc->group == IPG_PLAYER4) input_seq_set_1(&typedesc->seq[SEQ_TYPE_STANDARD], INPUT_CODE_SET_DEVINDEX(JOYCODE_BUTTON1, 3)); break; case IPT_AD_STICK_Z: case IPT_START: case IPT_SELECT: input_seq_set_0(&typedesc->seq[SEQ_TYPE_STANDARD]); break; //default: //input_seq_set_0(&typedesc->seq[SEQ_TYPE_STANDARD]); } } }
static void startup_callback(running_machine &machine) { /** * If the special input ports have not been configured yet, do so now. * This is the earliest opportunity we have to do this, which must be done * after osd_customize_input_type_list. **/ if (!g_state.special_inputs_configured) { g_state.special_inputs_configured = true; input_device *keyboard = 0; input_item_id keyboard_item = ITEM_ID_A; int keyboard_count = 0; int special_button_index = 0; ioport_list &ioportlist = g_state.machine->m_portlist; const input_port_config *port; const input_field_config *field; for (port = ioportlist.first(); port; port = port->next()) { for (field = port->fieldlist; field; field = field->next) { if ((field->type != IPT_OTHER) || !field->name) { continue; } if (!keyboard || (keyboard_item > ITEM_ID_Z)) { char namebuf[256]; snprintf(namebuf, sizeof(namebuf), "libmame_virtual_special_keyboard_%d", keyboard_count++); keyboard = input_device_add (g_state.machine, DEVICE_CLASS_KEYBOARD, namebuf, NULL); keyboard_item = ITEM_ID_A; } keyboard_item++; int input_code = INPUT_CODE(DEVICE_CLASS_KEYBOARD, input_device_get_index(g_state.machine, keyboard), ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, keyboard_item); input_device_item_add(keyboard, "", (void *) special_button_index++, keyboard_item, &get_special_state); input_field_user_settings settings; input_seq_set_1(&(settings.seq[SEQ_TYPE_STANDARD]), input_code); input_field_set_user_settings(field, &settings); } } } LibMame_StartupPhase phase; switch (machine.init_phase()) { case STARTUP_PHASE_PREPARING: phase = LibMame_StartupPhase_Preparing; break; case STARTUP_PHASE_LOADING_ROMS: phase = LibMame_StartupPhase_LoadingRoms; break; case STARTUP_PHASE_INITIALIZING_STATE: phase = LibMame_StartupPhase_InitializingMachine; break; default: /* Else ignore, unknown phase? */ return; } /* Currently, only one running game at a time is supported, so just pass in a bogus value */ (*(g_state.callbacks->StartingUp)) (phase, machine.init_phase_percent_complete(), (LibMame_RunningGame *) 0x1, g_state.callback_data); }