WIP on supporting custom controller defaults

This commit is contained in:
UnknownShadow200 2024-07-13 12:48:11 +10:00
parent 9ea54dee7c
commit 736e20d0d8
20 changed files with 127 additions and 100 deletions

View File

@ -309,7 +309,7 @@ static const struct InputDevice padDevice = {
/* Launcher buttons */
CCPAD_3,
/* Bindings */
"pad-%c", PadBind_Defaults, PadBind_Mappings
"pad-%c", NULL, NULL
};
struct InputDevice TouchDevice = {
INPUT_DEVICE_TOUCH, 0,
@ -441,15 +441,17 @@ void Gamepad_Tick(float delta) {
}
}
int Gamepad_MapPort(long deviceID) {
int Gamepad_Connect(long deviceID, const struct BindMapping_* defaults) {
int port;
for (port = 0; port < INPUT_MAX_GAMEPADS; port++)
{
if (Gamepad_Devices[port].deviceID == deviceID) return port;
if (Gamepad_Devices[port].deviceID != 0) continue;
Gamepad_Devices[port].deviceID = deviceID;
Gamepad_Devices[port].base.defaultBinds = defaults;
Gamepad_Devices[port].deviceID = deviceID;
InputBind_Load(&Gamepad_Devices[port]);
return port;
}
@ -461,7 +463,8 @@ int Gamepad_MapPort(long deviceID) {
/*########################################################################################################################*
*---------------------------------------------------------Keybinds--------------------------------------------------------*
*#########################################################################################################################*/
BindMapping PadBind_Mappings[BIND_COUNT];
/* The gamepad buttons that are bound to each input binding */
static BindMapping padBind_Mappings[INPUT_MAX_GAMEPADS][BIND_COUNT];
BindMapping KeyBind_Mappings[BIND_COUNT];
const BindMapping PadBind_Defaults[BIND_COUNT] = {
@ -610,11 +613,11 @@ static void OnInit(void) {
for (i = 0; i < INPUT_MAX_GAMEPADS; i++)
{
Mem_Copy(&Gamepad_Devices[i].base, &padDevice, sizeof(struct InputDevice));
Gamepad_Devices[i].base.index = i;
Gamepad_Devices[i].base.index = i;
Gamepad_Devices[i].base.currentBinds = &padBind_Mappings[i];
}
InputBind_Load(&NormDevice);
InputBind_Load(&padDevice);
}
static void OnFree(void) {

View File

@ -215,8 +215,7 @@ struct GamepadDevice {
float holdtime[GAMEPAD_BTN_COUNT];
};
extern struct GamepadDevice Gamepad_Devices[INPUT_MAX_GAMEPADS];
int Gamepad_MapPort(long deviceID);
int Gamepad_Connect(long deviceID, const struct BindMapping_* defaults);
/* Enumeration of all input bindings. */
@ -243,8 +242,6 @@ typedef struct BindMapping_ { cc_uint8 button1, button2; } BindMapping;
/* The keyboard/mouse buttons that are bound to each input binding */
extern BindMapping KeyBind_Mappings[BIND_COUNT];
/* The gamepad buttons that are bound to each input binding */
extern BindMapping PadBind_Mappings[BIND_COUNT];
/* Default keyboard/mouse button that each input binding is bound to */
extern const BindMapping KeyBind_Defaults[BIND_COUNT];
/* Default gamepad button that each input binding is bound to */

View File

@ -135,39 +135,40 @@ void Gamepads_Init(void) {
irrst_result = irrstInit();
}
static void HandleButtons(u32 mods) {
Gamepad_SetButton(0, CCPAD_L, mods & KEY_L);
Gamepad_SetButton(0, CCPAD_R, mods & KEY_R);
static void HandleButtons(int port, u32 mods) {
Gamepad_SetButton(port, CCPAD_L, mods & KEY_L);
Gamepad_SetButton(port, CCPAD_R, mods & KEY_R);
Gamepad_SetButton(0, CCPAD_1, mods & KEY_A);
Gamepad_SetButton(0, CCPAD_2, mods & KEY_B);
Gamepad_SetButton(0, CCPAD_3, mods & KEY_X);
Gamepad_SetButton(0, CCPAD_4, mods & KEY_Y);
Gamepad_SetButton(port, CCPAD_1, mods & KEY_A);
Gamepad_SetButton(port, CCPAD_2, mods & KEY_B);
Gamepad_SetButton(port, CCPAD_3, mods & KEY_X);
Gamepad_SetButton(port, CCPAD_4, mods & KEY_Y);
Gamepad_SetButton(0, CCPAD_START, mods & KEY_START);
Gamepad_SetButton(0, CCPAD_SELECT, mods & KEY_SELECT);
Gamepad_SetButton(port, CCPAD_START, mods & KEY_START);
Gamepad_SetButton(port, CCPAD_SELECT, mods & KEY_SELECT);
Gamepad_SetButton(0, CCPAD_LEFT, mods & KEY_DLEFT);
Gamepad_SetButton(0, CCPAD_RIGHT, mods & KEY_DRIGHT);
Gamepad_SetButton(0, CCPAD_UP, mods & KEY_DUP);
Gamepad_SetButton(0, CCPAD_DOWN, mods & KEY_DDOWN);
Gamepad_SetButton(port, CCPAD_LEFT, mods & KEY_DLEFT);
Gamepad_SetButton(port, CCPAD_RIGHT, mods & KEY_DRIGHT);
Gamepad_SetButton(port, CCPAD_UP, mods & KEY_DUP);
Gamepad_SetButton(port, CCPAD_DOWN, mods & KEY_DDOWN);
Gamepad_SetButton(0, CCPAD_ZL, mods & KEY_ZL);
Gamepad_SetButton(0, CCPAD_ZR, mods & KEY_ZR);
Gamepad_SetButton(port, CCPAD_ZL, mods & KEY_ZL);
Gamepad_SetButton(port, CCPAD_ZR, mods & KEY_ZR);
}
#define AXIS_SCALE 8.0f
static void ProcessCircleInput(int axis, circlePosition* pos, float delta) {
static void ProcessCircleInput(int port, int axis, circlePosition* pos, float delta) {
// May not be exactly 0 on actual hardware
if (Math_AbsI(pos->dx) <= 24) pos->dx = 0;
if (Math_AbsI(pos->dy) <= 24) pos->dy = 0;
Gamepad_SetAxis(0, axis, pos->dx / AXIS_SCALE, -pos->dy / AXIS_SCALE, delta);
Gamepad_SetAxis(port, axis, pos->dx / AXIS_SCALE, -pos->dy / AXIS_SCALE, delta);
}
void Gamepads_Process(float delta) {
u32 mods = hidKeysDown() | hidKeysHeld();
HandleButtons(mods);
int port = Gamepad_Connect(0x3D5, PadBind_Defaults);
HandleButtons(port, mods);
circlePosition hid_pos;
hidCircleRead(&hid_pos);
@ -177,10 +178,10 @@ void Gamepads_Process(float delta) {
irrstScanInput();
irrstCstickRead(&stk_pos);
ProcessCircleInput(PAD_AXIS_RIGHT, &stk_pos, delta);
ProcessCircleInput(PAD_AXIS_LEFT, &hid_pos, delta);
ProcessCircleInput(port, PAD_AXIS_RIGHT, &stk_pos, delta);
ProcessCircleInput(port, PAD_AXIS_LEFT, &hid_pos, delta);
} else {
ProcessCircleInput(PAD_AXIS_RIGHT, &hid_pos, delta);
ProcessCircleInput(port, PAD_AXIS_RIGHT, &hid_pos, delta);
}
}

View File

@ -107,9 +107,15 @@ static int MapNativeKey(int code) {
static void JNICALL java_processKeyDown(JNIEnv* env, jobject o, jint code) {
int key = MapNativeKey(code);
Platform_Log2("KEY - DOWN %i,%i", &code, &key);
if (key) Input_SetPressed(key);
if (Input_IsPadButton(key)) Input.Sources |= INPUT_SOURCE_GAMEPAD;
if (Input_IsPadButton(key)) {
Input.Sources |= INPUT_SOURCE_GAMEPAD;
int port = Gamepad_Connect(0xAD01D, PadBind_Defaults);
Gamepad_SetButton(port, key);
} else {
if (key) Input_SetPressed(key);
}
}
static void JNICALL java_processKeyUp(JNIEnv* env, jobject o, jint code) {
@ -147,11 +153,13 @@ static void JNICALL java_processPointerMove(JNIEnv* env, jobject o, jint id, jin
}
static void JNICALL java_processJoystickL(JNIEnv* env, jobject o, jint x, jint y) {
Gamepad_SetAxis(0, PAD_AXIS_LEFT, x / 4096.0f, y / 4096.0f, 1.0f / 60);
int port = Gamepad_Connect(0xAD01D, PadBind_Defaults);
Gamepad_SetAxis(port, PAD_AXIS_LEFT, x / 4096.0f, y / 4096.0f, 1.0f / 60);
}
static void JNICALL java_processJoystickR(JNIEnv* env, jobject o, jint x, jint y) {
Gamepad_SetAxis(0, PAD_AXIS_RIGHT, x / 4096.0f, y / 4096.0f, 1.0f / 60);
int port = Gamepad_Connect(0xAD01D, PadBind_Defaults);
Gamepad_SetAxis(port, PAD_AXIS_RIGHT, x / 4096.0f, y / 4096.0f, 1.0f / 60);
}
static void JNICALL java_processSurfaceCreated(JNIEnv* env, jobject o, jobject surface) {

View File

@ -297,7 +297,7 @@ void Gamepads_Process(float delta) {
int dual_analog = cont_has_capabilities(cont, CONT_CAPABILITIES_DUAL_ANALOG);
if(dual_analog == -1) dual_analog = 0;
int port = Gamepad_MapPort(i + 10);
int port = Gamepad_Connect(0xDC + i, PadBind_Defaults);
HandleButtons(port, state->buttons);
HandleController(port, dual_analog, state, delta);
}

View File

@ -152,7 +152,7 @@ static void ProcessPADInput(int i, float delta) {
return; // not connected, still busy, etc
}
int port = Gamepad_MapPort(i + 10);
int port = Gamepad_Connect(0x5C + i, PadBind_Defaults);
ProcessPAD_Buttons(port, gc_pads[i].button);
ProcessPAD_Joystick(port, PAD_AXIS_LEFT, gc_pads[i].stickX, gc_pads[i].stickY, delta);
ProcessPAD_Joystick(port, PAD_AXIS_RIGHT, gc_pads[i].substickX, gc_pads[i].substickY, delta);
@ -421,7 +421,7 @@ static void ProcessWPADInput(int i, float delta) {
WPADData* wd = WPAD_Data(i);
u32 mods = wd->btns_h | wd->btns_d; // buttons held | buttons down now
int port = Gamepad_MapPort(i + 20);
int port = Gamepad_Connect(0x11 + i, PadBind_Defaults);
if (type == WPAD_EXP_CLASSIC) {
ProcessClassicInput(port, wd, delta);

View File

@ -39,24 +39,6 @@ void Window_Init(void) {
DisplayInfo.ContentOffsetX = 10;
DisplayInfo.ContentOffsetY = 10;
// change defaults to make more sense for N64
BindMapping* binds = (BindMapping*)PadBind_Defaults;
BindMapping_Set(&binds[BIND_JUMP], CCPAD_1, 0);
BindMapping_Set(&binds[BIND_INVENTORY], CCPAD_2, 0);
BindMapping_Set(&binds[BIND_PLACE_BLOCK], CCPAD_5, 0);
BindMapping_Set(&binds[BIND_HOTBAR_RIGHT], CCPAD_L, 0);
BindMapping_Set(&binds[BIND_DELETE_BLOCK], CCPAD_R, 0);
BindMapping_Set(&binds[BIND_FORWARD], CCPAD_CUP, 0);
BindMapping_Set(&binds[BIND_BACK], CCPAD_CDOWN, 0);
BindMapping_Set(&binds[BIND_LEFT], CCPAD_CLEFT, 0);
BindMapping_Set(&binds[BIND_RIGHT], CCPAD_CRIGHT, 0);
BindMapping_Set(&binds[BIND_FLY_UP], CCPAD_UP, 0);
BindMapping_Set(&binds[BIND_FLY_DOWN], CCPAD_DOWN, 0);
BindMapping_Set(&binds[BIND_SPEED], CCPAD_LEFT, 0);
BindMapping_Set(&binds[BIND_FLY], CCPAD_RIGHT, 0);
}
void Window_Free(void) { }
@ -98,6 +80,26 @@ void Window_UpdateRawMouse(void) { }
/*########################################################################################################################*
*-------------------------------------------------------Gamepads----------------------------------------------------------*
*#########################################################################################################################*/
static const BindMapping default_n64[BIND_COUNT] = {
[BIND_FORWARD] = { CCPAD_CUP, 0 },
[BIND_BACK] = { CCPAD_CDOWN, 0 },
[BIND_LEFT] = { CCPAD_CLEFT, 0 },
[BIND_RIGHT] = { CCPAD_CRIGHT, 0 },
[BIND_FLY_UP] = { CCPAD_UP, 0 },
[BIND_FLY_DOWN]= { CCPAD_DOWN, 0 },
[BIND_SPEED] = { CCPAD_LEFT, 0 },
[BIND_FLY] = { CCPAD_RIGHT, 0 },
[BIND_JUMP] = { CCPAD_1, 0 },
[BIND_INVENTORY] = { CCPAD_2, 0 },
[BIND_PLACE_BLOCK] = { CCPAD_5, 0 },
[BIND_HOTBAR_RIGHT] = { CCPAD_L, 0 },
[BIND_DELETE_BLOCK] = { CCPAD_R, 0 },
[BIND_SET_SPAWN] = { CCPAD_START, 0 },
};
void Gamepads_Init(void) {
Input.Sources |= INPUT_SOURCE_GAMEPAD;
joypad_init();
@ -141,7 +143,7 @@ void Gamepads_Process(float delta) {
for (int i = 0; i < INPUT_MAX_GAMEPADS; i++)
{
if (!joypad_is_connected(i)) continue;
int port = Gamepad_MapPort(i + 10);
int port = Gamepad_Connect(0x64 + i, default_n64);
joypad_inputs_t inputs = joypad_get_inputs(i);
HandleButtons(port, inputs.btn);

View File

@ -233,23 +233,24 @@ void Gamepads_Init(void) {
}
void Gamepads_Process(float delta) {
int port = Gamepad_Connect(0xD5, PadBind_Defaults);
int mods = keysDown() | keysHeld();
Gamepad_SetButton(0, CCPAD_L, mods & KEY_L);
Gamepad_SetButton(0, CCPAD_R, mods & KEY_R);
Gamepad_SetButton(port, CCPAD_L, mods & KEY_L);
Gamepad_SetButton(port, CCPAD_R, mods & KEY_R);
Gamepad_SetButton(0, CCPAD_1, mods & KEY_A);
Gamepad_SetButton(0, CCPAD_2, mods & KEY_B);
Gamepad_SetButton(0, CCPAD_3, mods & KEY_X);
Gamepad_SetButton(0, CCPAD_4, mods & KEY_Y);
Gamepad_SetButton(port, CCPAD_1, mods & KEY_A);
Gamepad_SetButton(port, CCPAD_2, mods & KEY_B);
Gamepad_SetButton(port, CCPAD_3, mods & KEY_X);
Gamepad_SetButton(port, CCPAD_4, mods & KEY_Y);
Gamepad_SetButton(0, CCPAD_START, mods & KEY_START);
Gamepad_SetButton(0, CCPAD_SELECT, mods & KEY_SELECT);
Gamepad_SetButton(port, CCPAD_START, mods & KEY_START);
Gamepad_SetButton(port, CCPAD_SELECT, mods & KEY_SELECT);
Gamepad_SetButton(0, CCPAD_LEFT, mods & KEY_LEFT);
Gamepad_SetButton(0, CCPAD_RIGHT, mods & KEY_RIGHT);
Gamepad_SetButton(0, CCPAD_UP, mods & KEY_UP);
Gamepad_SetButton(0, CCPAD_DOWN, mods & KEY_DOWN);
Gamepad_SetButton(port, CCPAD_LEFT, mods & KEY_LEFT);
Gamepad_SetButton(port, CCPAD_RIGHT, mods & KEY_RIGHT);
Gamepad_SetButton(port, CCPAD_UP, mods & KEY_UP);
Gamepad_SetButton(port, CCPAD_DOWN, mods & KEY_DOWN);
}

View File

@ -151,7 +151,9 @@ static void ProcessPadInput(int port, PADTYPE* pad, float delta) {
void Gamepads_Process(float delta) {
PADTYPE* pad = (PADTYPE*)&pad_buff[0][0];
if (pad->stat == 0) ProcessPadInput(0, pad, delta);
int port = Gamepad_Connect(0x503, PadBind_Defaults);
if (pad->stat == 0) ProcessPadInput(port, pad, delta);
}

View File

@ -247,19 +247,22 @@ static void ProcessPadInput(int port, float delta, struct padButtonStatus* pad)
}
static cc_bool setMode[INPUT_MAX_GAMEPADS];
static void ProcessPad(int port, float delta) {
struct padButtonStatus pad;
int state = padGetState(port, 0);
static void ProcessPad(int i, float delta) {
struct padButtonStatus pad;
int state = padGetState(i, 0);
if (state != PAD_STATE_STABLE) return;
// Change to DUALSHOCK mode so analog joysticks return values
if (!setMode[port]) {
padSetMainMode(port, 0, PAD_MMODE_DUALSHOCK, PAD_MMODE_LOCK);
setMode[port] = true;
if (!setMode[i]) {
padSetMainMode(i, 0, PAD_MMODE_DUALSHOCK, PAD_MMODE_LOCK);
setMode[i] = true;
}
int ret = padRead(port, 0, &pad);
if (ret != 0) ProcessPadInput(port, delta, &pad);
int ret = padRead(i, 0, &pad);
if (ret == 0) return;
int port = Gamepad_Connect(0x503 + i, PadBind_Defaults);
ProcessPadInput(port, delta, &pad);
}
void Gamepads_Process(float delta) {

View File

@ -325,10 +325,10 @@ void Gamepads_Process(float delta) {
ioPadGetInfo(&pad_info);
for (int i = 0; i < INPUT_MAX_GAMEPADS; i++)
{
if (!pad_info.status[i]) continue;
if (!pad_info.status[i]) continue;
ioPadGetData(i, &pad_data);
int port = Gamepad_MapPort(i + 10);
int port = Gamepad_Connect(0x503 + i, PadBind_Defaults);
ProcessPadInput(port, delta, &pad_data);
}
}

View File

@ -126,14 +126,16 @@ static void ProcessCircleInput(int port, SceCtrlData* pad, float delta) {
}
void Gamepads_Process(float delta) {
int port = Gamepad_Connect(0x5O3, PadBind_Defaults);
SceCtrlData pad;
/* TODO implement */
int ret = sceCtrlPeekBufferPositive(&pad, 1);
if (ret <= 0) return;
// TODO: need to use cached version still? like GameCube/Wii
HandleButtons(0, pad.Buttons);
ProcessCircleInput(0, &pad, delta);
HandleButtons(port, pad.Buttons);
ProcessCircleInput(port, &pad, delta);
}

View File

@ -176,6 +176,7 @@ static void ProcessCircleInput(int port, int axis, int x, int y, float delta) {
}
static void ProcessPadInput(float delta) {
int port = Gamepad_Connect(0x5O3, PadBind_Defaults);
SceCtrlData pad;
// sceCtrlReadBufferPositive is blocking (seems to block until vblank), and don't want that
@ -184,9 +185,9 @@ static void ProcessPadInput(float delta) {
if (res < 0) return; // error occurred
// TODO: need to use cached version still? like GameCube/Wii
HandleButtons(0, pad.buttons);
ProcessCircleInput(0, PAD_AXIS_LEFT, pad.lx - 127, pad.ly - 127, delta);
ProcessCircleInput(0, PAD_AXIS_RIGHT, pad.rx - 127, pad.ry - 127, delta);
HandleButtons(port, pad.buttons);
ProcessCircleInput(port, PAD_AXIS_LEFT, pad.lx - 127, pad.ly - 127, delta);
ProcessCircleInput(port, PAD_AXIS_RIGHT, pad.rx - 127, pad.ry - 127, delta);
}
void Gamepads_Process(float delta) {

View File

@ -522,7 +522,7 @@ void Gamepads_Process(float delta) {
{
SDL_GameController* gp = controllers[i];
if (!gp) continue;
int port = Gamepad_MapPort(i + 10);
int port = Gamepad_Connect(0x5D12 + i, PadBind_Defaults);
ProcessGamepadButtons(port, gp);
ProcessJoystick(port, gp, PAD_AXIS_LEFT, delta);

View File

@ -555,7 +555,7 @@ void Gamepads_Process(float delta) {
{
SDL_Gamepad* gp = controllers[i];
if (!gp) continue;
int port = Gamepad_MapPort(i + 10);
int port = Gamepad_Connect(0x5D13 + i, PadBind_Defaults);
ProcessGamepadButtons(port, gp);
ProcessJoystick(port, gp, PAD_AXIS_LEFT, delta);

View File

@ -129,10 +129,11 @@ static smpc_peripheral_digital_t dig_state;
static smpc_peripheral_analog_t ana_state;
void Gamepads_Process(float delta) {
int port = Gamepad_Connect(0x5A, PadBind_Defaults);
smpc_peripheral_process();
smpc_peripheral_digital_port(1, &dig_state);
ProcessButtons(0, dig_state.pressed.raw | dig_state.held.raw);
ProcessButtons(port, dig_state.pressed.raw | dig_state.held.raw);
smpc_peripheral_analog_port(1, &ana_state);
}

View File

@ -180,14 +180,15 @@ static void ProcessJoystickInput(int port, int axis, HidAnalogStickState* pos, f
}
void Gamepads_Process(float delta) {
int port = Gamepad_Connect(0x51C, PadBind_Defaults);
u64 keys = padGetButtons(&pad);
HandleButtons(0, keys);
HandleButtons(port, keys);
// Read the sticks' position
HidAnalogStickState analog_stick_l = padGetStickPos(&pad, 0);
HidAnalogStickState analog_stick_r = padGetStickPos(&pad, 1);
ProcessJoystickInput(0, PAD_AXIS_LEFT, &analog_stick_l, delta);
ProcessJoystickInput(0, PAD_AXIS_RIGHT, &analog_stick_r, delta);
ProcessJoystickInput(port, PAD_AXIS_LEFT, &analog_stick_l, delta);
ProcessJoystickInput(port, PAD_AXIS_RIGHT, &analog_stick_r, delta);
}

View File

@ -621,7 +621,7 @@ static void ProcessGamepadInput(int port, EmscriptenGamepadEvent* ev, float delt
}
void Gamepads_Process(float delta) {
int i, res, count;
int i, port, res, count;
Input.Sources = INPUT_SOURCE_NORMAL;
if (emscripten_sample_gamepad_data() != 0) return;
@ -631,7 +631,10 @@ void Gamepads_Process(float delta) {
{
EmscriptenGamepadEvent ev;
res = emscripten_get_gamepad_status(i, &ev);
if (res == 0) ProcessGamepadInput(i, &ev, delta);
if (res != 0) continue;
port = Gamepad_Connect(0xEB + i, PadBind_Defaults);
ProcessGamepadInput(port, &ev, delta);
}
}

View File

@ -182,10 +182,11 @@ void Gamepads_Process(float delta) {
usbh_pooling_hubs();
#endif
if (!xid_ctrl) return;
int port = Gamepad_Connect(0xB0, PadBind_Defaults);
HandleButtons(0, &gp_state);
HandleJoystick(0, PAD_AXIS_LEFT, gp_state.leftStickX, gp_state.leftStickY, delta);
HandleJoystick(0, PAD_AXIS_RIGHT, gp_state.rightStickX, gp_state.rightStickY, delta);
HandleButtons(port, &gp_state);
HandleJoystick(port, PAD_AXIS_LEFT, gp_state.leftStickX, gp_state.leftStickY, delta);
HandleJoystick(port, PAD_AXIS_RIGHT, gp_state.rightStickX, gp_state.rightStickY, delta);
}

View File

@ -132,14 +132,15 @@ static void HandleJoystick(int port, int axis, int x, int y, float delta) {
void Gamepads_Process(float delta) {
usb_do_poll();
int port = Gamepad_Connect(0xB0360, PadBind_Defaults);
struct controller_data_s pad;
int res = get_controller_data(&pad, 0);
if (res == 0) return;
HandleButtons(0, &pad);
HandleJoystick(0, PAD_AXIS_LEFT, pad.s1_x, pad.s1_y, delta);
HandleJoystick(0, PAD_AXIS_RIGHT, pad.s2_x, pad.s2_y, delta);
HandleButtons(port, &pad);
HandleJoystick(port, PAD_AXIS_LEFT, pad.s1_x, pad.s1_y, delta);
HandleJoystick(port, PAD_AXIS_RIGHT, pad.s2_x, pad.s2_y, delta);
}