diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/dfinput/pad.c | 287 | ||||
-rw-r--r-- | plugins/dfinput/pad.h | 2 |
2 files changed, 289 insertions, 0 deletions
diff --git a/plugins/dfinput/pad.c b/plugins/dfinput/pad.c new file mode 100644 index 0000000..c522117 --- /dev/null +++ b/plugins/dfinput/pad.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2009, Wei Mingzhi <whistler@openoffice.org>. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses>. + * + * this is only pure emulation code to handle analogs, + * extracted from dfinput. + */ + +#include <stdint.h> + +#include "../../libpcsxcore/psemu_plugin_defs.h" + +enum { + ANALOG_LEFT = 0, + ANALOG_RIGHT, + + ANALOG_TOTAL +}; + +enum { + CMD_READ_DATA_AND_VIBRATE = 0x42, + CMD_CONFIG_MODE = 0x43, + CMD_SET_MODE_AND_LOCK = 0x44, + CMD_QUERY_MODEL_AND_MODE = 0x45, + CMD_QUERY_ACT = 0x46, // ?? + CMD_QUERY_COMB = 0x47, // ?? + CMD_QUERY_MODE = 0x4C, // QUERY_MODE ?? + CMD_VIBRATION_TOGGLE = 0x4D, +}; + +static struct { + uint8_t PadMode; + uint8_t PadID; + PadDataS pad; +} padstate[2]; + +static uint8_t stdpar[2][8] = { + {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80}, + {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80} +}; + +static uint8_t unk46[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}, + {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A} +}; + +static uint8_t unk47[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}, + {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00} +}; + +static uint8_t unk4c[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; + +static uint8_t unk4d[2][8] = { + {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +}; + +static uint8_t stdcfg[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; + +static uint8_t stdmode[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; + +static uint8_t stdmodel[2][8] = { + {0xFF, + 0x5A, + 0x01, // 03 - dualshock2, 01 - dualshock + 0x02, // number of modes + 0x01, // current mode: 01 - analog, 00 - digital + 0x02, + 0x01, + 0x00}, + {0xFF, + 0x5A, + 0x01, // 03 - dualshock2, 01 - dualshock + 0x02, // number of modes + 0x01, // current mode: 01 - analog, 00 - digital + 0x02, + 0x01, + 0x00} +}; + +static uint8_t CurPad = 0, CurByte = 0, CurCmd = 0, CmdLen = 0; +static uint8_t *buf; + +static uint8_t do_cmd(void) +{ + PadDataS *pad = &padstate[CurPad].pad; + int pad_num = CurPad; + + CmdLen = 8; + switch (CurCmd) { + case CMD_CONFIG_MODE: + buf = stdcfg[pad_num]; + if (stdcfg[pad_num][3] == 0xFF) return 0xF3; + else return padstate[pad_num].PadID; + + case CMD_SET_MODE_AND_LOCK: + buf = stdmode[pad_num]; + return 0xF3; + + case CMD_QUERY_MODEL_AND_MODE: + buf = stdmodel[pad_num]; + buf[4] = padstate[pad_num].PadMode; + return 0xF3; + + case CMD_QUERY_ACT: + buf = unk46[pad_num]; + return 0xF3; + + case CMD_QUERY_COMB: + buf = unk47[pad_num]; + return 0xF3; + + case CMD_QUERY_MODE: + buf = unk4c[pad_num]; + return 0xF3; + + case CMD_VIBRATION_TOGGLE: + buf = unk4d[pad_num]; + return 0xF3; + + case CMD_READ_DATA_AND_VIBRATE: + default: + buf = stdpar[pad_num]; + + buf[2] = pad->buttonStatus; + buf[3] = pad->buttonStatus >> 8; + + if (padstate[pad_num].PadMode == 1) { + buf[4] = pad->rightJoyX; + buf[5] = pad->rightJoyY; + buf[6] = pad->leftJoyX; + buf[7] = pad->leftJoyY; + } else { + CmdLen = 4; + } + + return padstate[pad_num].PadID; + } +} + +static void do_cmd2(unsigned char value) +{ + switch (CurCmd) { + case CMD_CONFIG_MODE: + switch (value) { + case 0: + buf[2] = 0; + buf[3] = 0; + break; + + case 1: + buf[2] = 0xFF; + buf[3] = 0xFF; + break; + } + break; + + case CMD_SET_MODE_AND_LOCK: + padstate[CurPad].PadMode = value; + padstate[CurPad].PadID = value ? 0x73 : 0x41; + break; + + case CMD_QUERY_ACT: + switch (value) { + case 0: // default + buf[5] = 0x02; + buf[6] = 0x00; + buf[7] = 0x0A; + break; + + case 1: // Param std conf change + buf[5] = 0x01; + buf[6] = 0x01; + buf[7] = 0x14; + break; + } + break; + + case CMD_QUERY_MODE: + switch (value) { + case 0: // mode 0 - digital mode + buf[5] = PSE_PAD_TYPE_STANDARD; + break; + + case 1: // mode 1 - analog mode + buf[5] = PSE_PAD_TYPE_ANALOGPAD; + break; + } + break; + } +} + +static unsigned char PADpoll_(unsigned char value) { + + if (CurByte == 0) { + CurCmd = value; + CurByte++; + + // Don't enable Analog/Vibration for a standard pad + if (padstate[CurPad].pad.controllerType != PSE_PAD_TYPE_ANALOGPAD) + CurCmd = CMD_READ_DATA_AND_VIBRATE; + + return do_cmd(); + } + + if (CurByte == 2) + do_cmd2(value); + + if (CurByte >= CmdLen) + return 0; + + return buf[CurByte++]; +} + +#include <stdio.h> +static unsigned char PADpoll(unsigned char value) { + unsigned char b = CurByte, r = PADpoll_(value); + printf("poll[%d] %02x %02x\n", b, value, r); + return r; +} + +/* hack.. */ +extern long (*PAD1_readPort1)(PadDataS *pad); + +static unsigned char PADstartPoll1(int pad) { + CurPad = 0; + CurByte = 0; + + PAD1_readPort1(&padstate[0].pad); + + return 0xFF; +} + +/* some more hacks here but oh well */ +extern void *PAD1_startPoll, *PAD1_poll; + +void dfinput_activate(int yes) +{ + static void *old_start, *old_poll; + + if (!yes) { + if (PAD1_startPoll == PADstartPoll1) + PAD1_startPoll = old_start; + if (PAD1_poll == PADpoll) + PAD1_poll = old_poll; + return; + } + + if (PAD1_startPoll == PADstartPoll1 && PAD1_poll == PADpoll) + return; + + old_start = PAD1_startPoll; + old_poll = PAD1_poll; + PAD1_startPoll = PADstartPoll1; + PAD1_poll = PADpoll; + + PAD1_readPort1(&padstate[0].pad); + padstate[0].PadID = padstate[0].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD ? 0x73 : 0x41; + padstate[0].PadMode = padstate[0].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD; + + padstate[1].PadID = 0x41; + padstate[1].PadMode = 0; +} + diff --git a/plugins/dfinput/pad.h b/plugins/dfinput/pad.h new file mode 100644 index 0000000..60a46f0 --- /dev/null +++ b/plugins/dfinput/pad.h @@ -0,0 +1,2 @@ +void dfinput_activate(int yes); + |