input: fix arcade mode for on-screen gamepads.

Use same layout as gamepad arcade for on-screen gamepads (ABXYRL)
map RT and LT to buttons 5 and 6 in arcade
android: Fix non-working fast-forward button
Use maple port in lastAxisValue state
naomi: use default alienfnt buttons: 1-4
This commit is contained in:
Flyinghead 2021-09-21 15:56:01 +02:00
parent c419654a11
commit 1725dbfa98
13 changed files with 89 additions and 48 deletions

View File

@ -110,9 +110,9 @@ static InputDescriptors _18wheelr_inputs = {
static InputDescriptors alienfnt_inputs = {
{
{ NAOMI_BTN0_KEY, "LEFT SHOT" },
{ NAOMI_BTN5_KEY, "ROTATION R", NAOMI_BTN1_KEY },
{ NAOMI_BTN1_KEY, "RIGHT SHOT", NAOMI_BTN2_KEY },
{ NAOMI_BTN4_KEY, "ROTATION L", NAOMI_BTN3_KEY },
{ NAOMI_BTN1_KEY, "ROTATION R" },
{ NAOMI_BTN2_KEY, "RIGHT SHOT" },
{ NAOMI_BTN3_KEY, "ROTATION L" },
NAO_START_DESC
NAO_BASE_BTN_DESC
},

View File

@ -237,11 +237,11 @@ bool GamepadDevice::gamepad_axis_input(u32 code, int value)
}
else if ((key & DC_BTN_GROUP_MASK) == EMU_BUTTONS) // Map triggers to emu buttons
{
int lastValue = lastAxisValue[key];
int lastValue = lastAxisValue[port][key];
int newValue = std::abs(v);
if ((lastValue < 16384 && newValue >= 16384) || (lastValue >= 16384 && newValue < 16384))
handleButtonInput(port, key, newValue >= 16384);
lastAxisValue[key] = newValue;
lastAxisValue[port][key] = newValue;
}
else
return false;

View File

@ -140,7 +140,7 @@ private:
input_detected_cb _input_detected;
bool _remappable;
u32 digitalToAnalogState[4];
std::map<DreamcastKey, int> lastAxisValue;
std::map<DreamcastKey, int> lastAxisValue[4];
static std::vector<std::shared_ptr<GamepadDevice>> _gamepads;
static std::mutex _gamepads_mutex;

View File

@ -105,6 +105,9 @@ public:
for (int i = 0; i < 32; i++)
set_button(0, (DreamcastKey)(1 << i), 1 << i);
set_button(0, EMU_BTN_FFORWARD, EMU_BTN_FFORWARD);
set_button(0, EMU_BTN_MENU, EMU_BTN_MENU);
set_button(0, EMU_BTN_ESCAPE, EMU_BTN_ESCAPE);
set_axis(0, DC_AXIS_LEFT, DC_AXIS_LEFT, true);
set_axis(0, DC_AXIS_RIGHT, DC_AXIS_RIGHT, true);
set_axis(0, DC_AXIS_UP, DC_AXIS_UP, true);

View File

@ -106,8 +106,8 @@ const std::vector<OSDVertex>& GetOSDVertices()
DrawButton2(vjoy_pos[2], kcode[0] & DC_DPAD_RIGHT);
DrawButton2(vjoy_pos[3], kcode[0] & DC_DPAD_DOWN);
DrawButton2(vjoy_pos[4], kcode[0] & DC_BTN_X);
DrawButton2(vjoy_pos[5], kcode[0] & DC_BTN_Y);
DrawButton2(vjoy_pos[4], kcode[0] & (settings.platform.system == DC_PLATFORM_DREAMCAST ? DC_BTN_X : DC_BTN_C));
DrawButton2(vjoy_pos[5], kcode[0] & (settings.platform.system == DC_PLATFORM_DREAMCAST ? DC_BTN_Y : DC_BTN_X));
DrawButton2(vjoy_pos[6], kcode[0] & DC_BTN_B);
DrawButton2(vjoy_pos[7], kcode[0] & DC_BTN_A);

View File

@ -79,7 +79,7 @@ public:
if (Gamepad)
{
// 1 2 3 4 5 6
// A B X Y L R
// A B X Y R L
map_button(SDL_CONTROLLER_BUTTON_A, DC_BTN_A);
map_button(SDL_CONTROLLER_BUTTON_B, DC_BTN_B);
map_button(SDL_CONTROLLER_BUTTON_X, DC_BTN_C);
@ -88,11 +88,11 @@ public:
if (!map_axis(SDL_CONTROLLER_AXIS_TRIGGERLEFT, DC_AXIS_LT, true))
map_button(SDL_CONTROLLER_BUTTON_LEFTSHOULDER, DC_AXIS_LT);
else
map_button(SDL_CONTROLLER_BUTTON_LEFTSHOULDER, DC_BTN_Y);
map_button(SDL_CONTROLLER_BUTTON_LEFTSHOULDER, DC_BTN_Z);
if (!map_axis(SDL_CONTROLLER_AXIS_TRIGGERRIGHT, DC_AXIS_RT, true))
map_button(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, DC_AXIS_RT);
else
map_button(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, DC_BTN_Z);
map_button(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, DC_BTN_Y);
}
else
{

View File

@ -30,7 +30,6 @@ public:
if (scancodes[port][i] != 0)
input_mapper->set_button(port, key, (u32)scancodes[port][i]);
}
input_mapper->version = 2;
save_mapping();
}
}

View File

@ -179,6 +179,7 @@ public class VirtualJoystickDelegate {
float tx = (width - 640.0f * scl) / 2;
int rv = 0xFFFFFFFF;
boolean fastForward = false;
int aid = event.getActionMasked();
int pid = event.getActionIndex();
@ -258,8 +259,10 @@ public class VirtualJoystickDelegate {
if (editVjoyMode) {
selectedVjoyElement = getElementIdFromButtonId(j);
resetEditMode();
} else
rv &= ~(int) vjoy[j][4];
} else if (vjoy[j][4] == VJoy.key_CONT_FFORWARD)
fastForward = true;
else
rv &= ~(int)vjoy[j][4];
}
}
}
@ -301,6 +304,7 @@ public class VirtualJoystickDelegate {
reset_analog();
anal_id = -1;
rv = 0xFFFFFFFF;
fastForward = false;
right_trigger = 0;
left_trigger = 0;
lt_id = -1;
@ -356,9 +360,9 @@ public class VirtualJoystickDelegate {
}
int joyx = get_anal(11, 0);
int joyy = get_anal(11, 1);
InputDeviceManager.getInstance().virtualGamepadEvent(rv, joyx, joyy, left_trigger, right_trigger);
InputDeviceManager.getInstance().virtualGamepadEvent(rv, joyx, joyy, left_trigger, right_trigger, fastForward);
// Only register the mouse event if no virtual gamepad button is down
if ((!editVjoyMode && rv == 0xFFFFFFFF && left_trigger == 0 && right_trigger == 0 && joyx == 0 && joyy == 0)
if ((!editVjoyMode && rv == 0xFFFFFFFF && left_trigger == 0 && right_trigger == 0 && joyx == 0 && joyy == 0 && !fastForward)
|| JNIdc.guiIsOpen())
InputDeviceManager.getInstance().mouseEvent(mouse_pos[0], mouse_pos[1], mouse_btns);
return(true);

View File

@ -105,7 +105,7 @@ public final class InputDeviceManager implements InputManager.InputDeviceListene
}
public native void init();
public native void virtualGamepadEvent(int kcode, int joyx, int joyy, int lt, int rt);
public native void virtualGamepadEvent(int kcode, int joyx, int joyy, int lt, int rt, boolean fastForward);
public native boolean joystickButtonEvent(int id, int button, boolean pressed);
public native boolean joystickAxisEvent(int id, int button, int value);
public native void mouseEvent(int xpos, int ypos, int buttons);

View File

@ -16,7 +16,7 @@ public class VJoy {
public static final int key_CONT_DPAD_RIGHT = 0x0080;
public static final int key_CONT_Y = 0x0200;
public static final int key_CONT_X = 0x0400;
public static final int key_CONT_FFORWARD = 0x100000;
public static final int key_CONT_FFORWARD = 0x3000002;
public static final int BTN_LTRIG = -1;
public static final int BTN_RTRIG = -2;

View File

@ -549,11 +549,11 @@ extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_periph_InputDeviceMa
AndroidGamepadDevice::RemoveAndroidGamepad(device);
}
extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_virtualGamepadEvent(JNIEnv *env, jobject obj, jint kcode, jint joyx, jint joyy, jint lt, jint rt)
extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_virtualGamepadEvent(JNIEnv *env, jobject obj, jint kcode, jint joyx, jint joyy, jint lt, jint rt, jboolean fastForward)
{
std::shared_ptr<AndroidGamepadDevice> device = AndroidGamepadDevice::GetAndroidGamepad(AndroidGamepadDevice::VIRTUAL_GAMEPAD_ID);
if (device != NULL)
device->virtual_gamepad_event(kcode, joyx, joyy, lt, rt);
device->virtual_gamepad_event(kcode, joyx, joyy, lt, rt, fastForward);
}
extern "C" JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_joystickButtonEvent(JNIEnv *env, jobject obj, jint id, jint key, jboolean pressed)

View File

@ -237,7 +237,7 @@ public:
GamepadDevice::Unregister(gamepad);
};
void virtual_gamepad_event(int kcode, int joyx, int joyy, int lt, int rt)
void virtual_gamepad_event(int kcode, int joyx, int joyy, int lt, int rt, bool fastForward)
{
// No virtual gamepad when the GUI is open: touch events only
if (gui_is_open())
@ -245,17 +245,37 @@ public:
kcode = 0xffffffff;
joyx = joyy = rt = lt = 0;
}
if (rt > 0)
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
{
if ((kcode & DC_BTN_A) == 0)
// RT + A -> D (coin)
kcode &= ~DC_BTN_D;
if ((kcode & DC_BTN_B) == 0)
// RT + B -> Service
kcode &= ~DC_DPAD2_UP;
if (rt > 0)
{
if ((kcode & DC_BTN_A) == 0)
// RT + A -> D (coin)
kcode &= ~DC_BTN_D;
if ((kcode & DC_BTN_B) == 0)
// RT + B -> Service
kcode &= ~DC_DPAD2_UP;
if ((kcode & DC_BTN_X) == 0)
// RT + X -> Test
kcode &= ~DC_DPAD2_DOWN;
}
// arcade mapping: X -> btn2, Y -> btn3
if ((kcode & DC_BTN_X) == 0)
// RT + X -> Test
kcode &= ~DC_DPAD2_DOWN;
{
kcode &= ~DC_BTN_C;
kcode |= DC_BTN_X;
}
if ((kcode & DC_BTN_Y) == 0)
{
kcode &= ~DC_BTN_X;
kcode |= DC_BTN_Y;
}
if (rt > 0)
// naomi btn4
kcode &= ~DC_BTN_Y;
if (lt > 0)
// naomi btn5
kcode &= ~DC_BTN_Z;
}
u32 changes = kcode ^ previous_kcode;
for (int i = 0; i < 32; i++)
@ -272,6 +292,9 @@ public:
gamepad_axis_input(DC_AXIS_LT, lt == 0 ? 0 : 0x7fff);
gamepad_axis_input(DC_AXIS_RT, rt == 0 ? 0 : 0x7fff);
previous_kcode = kcode;
if (fastForward != previousFastForward)
gamepad_btn_input(EMU_BTN_FFORWARD, fastForward);
previousFastForward = fastForward;
}
void rumble(float power, float inclination, u32 duration_ms) override
@ -304,6 +327,7 @@ private:
int android_id;
static std::map<int, std::shared_ptr<AndroidGamepadDevice>> android_gamepads;
u32 previous_kcode = 0xffffffff;
bool previousFastForward = false;
std::vector<int> fullAxes;
std::vector<int> halfAxes;
};

View File

@ -504,11 +504,15 @@ public:
{
case IOS_BTN_L2:
gamepad_axis_input(IOS_AXIS_L2, pressed ? 0x7fff : 0);
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
GamepadDevice::gamepad_btn_input(IOS_BTN_L1, pressed); // Z, btn5
return true;
case IOS_BTN_R2:
if (!pressed && maple_port() >= 0 && maple_port() <= 3)
kcode[maple_port()] |= DC_BTN_C | DC_BTN_D | DC_BTN_Z;
kcode[maple_port()] |= DC_DPAD2_UP | DC_BTN_D | DC_DPAD2_DOWN;
gamepad_axis_input(IOS_AXIS_R2, pressed ? 0x7fff : 0);
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
GamepadDevice::gamepad_btn_input(IOS_BTN_Y, pressed); // Y, btn4
return true;
default:
if ((buttonState & ((1 << IOS_BTN_UP) | (1 << IOS_BTN_DOWN))) == ((1 << IOS_BTN_UP) | (1 << IOS_BTN_DOWN))
@ -522,26 +526,33 @@ public:
gui_open_settings();
return true;
}
// Arcade shortcuts
if ((buttonState & (1 << IOS_BTN_R2)) != 0 && maple_port() >= 0 && maple_port() <= 3)
if (settings.platform.system != DC_PLATFORM_DREAMCAST && maple_port() >= 0 && maple_port() <= 3)
{
u32& keycode = kcode[maple_port()];
switch (code) {
case IOS_BTN_A:
// RT + A -> D (coin)
keycode = pressed ? keycode & ~DC_BTN_D : keycode | DC_BTN_D;
break;
case IOS_BTN_B:
// RT + B -> Service
keycode = pressed ? keycode & ~DC_DPAD2_UP : keycode | DC_DPAD2_UP;
break;
case IOS_BTN_X:
// RT + X -> Test
keycode = pressed ? keycode & ~DC_DPAD2_DOWN : keycode | DC_DPAD2_DOWN;
break;
default:
break;
if ((buttonState & (1 << IOS_BTN_R2)) != 0)
{
switch (code) {
case IOS_BTN_A:
// RT + A -> D (coin)
keycode = pressed ? keycode & ~DC_BTN_D : keycode | DC_BTN_D;
break;
case IOS_BTN_B:
// RT + B -> Service
keycode = pressed ? keycode & ~DC_DPAD2_UP : keycode | DC_DPAD2_UP;
break;
case IOS_BTN_X:
// RT + X -> Test
keycode = pressed ? keycode & ~DC_DPAD2_DOWN : keycode | DC_DPAD2_DOWN;
break;
default:
break;
}
}
// arcade mapping: X -> btn2, Y -> btn3
if (code == IOS_BTN_X)
code = IOS_BTN_R1; // C, btn2
if (code == IOS_BTN_Y)
code = IOS_BTN_X; // btn3
}
return GamepadDevice::gamepad_btn_input(code, pressed);