MA_CTRL_DEV_NEXT,
MA_CTRL_NUBS_BTNS,
MA_CTRL_DEADZONE,
+ MA_CTRL_VIBRATION,
MA_CTRL_DONE,
MA_OPT_SAVECFG,
MA_OPT_SAVECFG_GAME,
CE_INTVAL(volume_boost),
CE_INTVAL(psx_clock),
CE_INTVAL(new_dynarec_hacks),
+ CE_INTVAL(in_enable_vibration),
};
static char *get_cd_label(void)
NULL
};
static const char h_nub_btns[] = "Experimental, keep this OFF if unsure. Select rescan after change.";
-static const char h_notsgun[] = "Don't trigger (shoot) when touching screen in gun games.";
+static const char h_notsgun[] = "Don't trigger (shoot) when touching screen in gun games.";
+static const char h_vibration[]= "Must select analog above and enable this ingame too.";
static menu_entry e_menu_keyconfig[] =
{
mee_enum ("Port 1 device", 0, in_type_sel1, men_in_type_sel),
mee_enum ("Port 2 device", 0, in_type_sel2, men_in_type_sel),
mee_onoff_h ("Nubs as buttons", MA_CTRL_NUBS_BTNS, in_evdev_allow_abs_only, 1, h_nub_btns),
+ mee_onoff_h ("Vibration", MA_CTRL_VIBRATION, in_enable_vibration, 1, h_vibration),
mee_range ("Analog deadzone", MA_CTRL_DEADZONE, analog_deadzone, 1, 99),
mee_onoff_h ("No TS Gun trigger", 0, g_opts, OPT_TSGUN_NOTRIGGER, h_notsgun),
mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg),
me_enable(e_menu_options, MA_OPT_DISP_OPTS, 0);
me_enable(e_menu_keyconfig, MA_CTRL_NUBS_BTNS, 0);
#else
+ me_enable(e_menu_keyconfig, MA_CTRL_VIBRATION, 0);
me_enable(e_menu_keyconfig, MA_CTRL_DEADZONE, 0);
#endif
}
void plat_step_volume(int is_up)
{
}
+
+void plat_trigger_vibrate(void)
+{
+}
{
}
+void plat_trigger_vibrate(void)
+{
+}
+
void plat_init(void)
{
const char *main_fb_name, *layer_fb_name;
[BTN_BASE5] = "Push",
};
+struct haptic_data {
+ int count;
+ struct {
+ short time, strength;
+ } actions[120];
+};
+
+#define HAPTIC_IOCTL_MAGIC 'I'
+#define HAPTIC_PLAY_PATTERN _IOW(HAPTIC_IOCTL_MAGIC, 4, struct haptic_data)
+#define HAPTIC_INDIVIDUAL_MODE _IOW(HAPTIC_IOCTL_MAGIC, 5, unsigned int)
+#define HAPTIC_SET_VIB_LEVEL _IOW(HAPTIC_IOCTL_MAGIC, 9, unsigned int)
+
+static int hapticdev = -1;
+static struct haptic_data haptic_seq;
+
+static int haptic_init(void)
+{
+ int i, ret, v1, v2;
+ char buf[128], *p;
+ FILE *f;
+
+ f = fopen("haptic.txt", "r");
+ if (f == NULL) {
+ perror("fopen(haptic.txt)");
+ return -1;
+ }
+
+ for (i = 0; i < sizeof(haptic_seq.actions) / sizeof(haptic_seq.actions[0]); ) {
+ p = fgets(buf, sizeof(buf), f);
+ if (p == NULL)
+ break;
+ while (*p != 0 && *p == ' ')
+ p++;
+ if (*p == 0 || *p == ';' || *p == '#')
+ continue;
+
+ ret = sscanf(buf, "%d %d", &v1, &v2);
+ if (ret != 2) {
+ fprintf(stderr, "can't parse: %s", buf);
+ continue;
+ }
+
+ haptic_seq.actions[i].time = v1;
+ haptic_seq.actions[i].strength = v2;
+ i++;
+ }
+ fclose(f);
+
+ if (i == 0) {
+ fprintf(stderr, "bad haptic.txt\n");
+ return -1;
+ }
+ haptic_seq.count = i;
+
+ hapticdev = open("/dev/isa1200", O_RDWR | O_NONBLOCK);
+ if (hapticdev == -1) {
+ perror("open(/dev/isa1200)");
+ return -1;
+ }
+
+ i = 0;
+ ret = ioctl(hapticdev, HAPTIC_INDIVIDUAL_MODE, &i); /* use 2 of them */
+ i = 3;
+ ret |= ioctl(hapticdev, HAPTIC_SET_VIB_LEVEL, &i); /* max */
+ if (ret != 0) {
+ fprintf(stderr, "haptic ioctls failed\n");
+ close(hapticdev);
+ hapticdev = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+void plat_trigger_vibrate(void)
+{
+ int ret;
+
+ if (hapticdev == -2)
+ return; // it's broken
+ if (hapticdev < 0) {
+ ret = haptic_init();
+ if (ret < 0) {
+ hapticdev = -2;
+ return;
+ }
+ }
+
+ ioctl(hapticdev, HAPTIC_PLAY_PATTERN, &haptic_seq);
+}
+
/* Wiz stuff */
struct in_default_bind in_gp2x_defbinds[] =
{
int in_type1, in_type2;
int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 };
int in_keystate, in_state_gun;
+int in_enable_vibration;
int pl_flip_cnt;
void *tsdev;
void *pl_vout_buf;
};
extern int in_type1, in_type2;
extern int in_keystate, in_state_gun, in_a1[2], in_a2[2];
+extern int in_enable_vibration;
void in_update_analogs(void);
extern void *pl_vout_buf;
{
}
+void plat_trigger_vibrate(void)
+{
+}
#define GUNIN_BTNB (1<<2)
#define GUNIN_TRIGGER2 (1<<3) /* offscreen trigger */
extern void pl_update_gun(int *xn, int *xres, int *y, int *in);
+
+/* vibration trigger to frontend */
+extern int in_enable_vibration;
+extern void plat_trigger_vibrate(void);
break;
}
break;
+
+ case CMD_READ_DATA_AND_VIBRATE:
+ if (value == 1 && CurPad == 0 && in_enable_vibration)
+ plat_trigger_vibrate();
+ break;
}
}