From b944a30eda75c36c94ef71e7768497801887612b Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 9 Dec 2011 18:35:09 +0200 Subject: [PATCH] add vibration support for Caanoo --- frontend/menu.c | 7 +++- frontend/plat_dummy.c | 4 ++ frontend/plat_omap.c | 4 ++ frontend/plat_pollux.c | 91 ++++++++++++++++++++++++++++++++++++++++++ frontend/plugin_lib.c | 1 + frontend/plugin_lib.h | 1 + maemo/hildon.c | 3 ++ plugins/dfinput/main.h | 4 ++ plugins/dfinput/pad.c | 5 +++ 9 files changed, 119 insertions(+), 1 deletion(-) diff --git a/frontend/menu.c b/frontend/menu.c index 53f296a2..f5d0415e 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -58,6 +58,7 @@ typedef enum MA_CTRL_DEV_NEXT, MA_CTRL_NUBS_BTNS, MA_CTRL_DEADZONE, + MA_CTRL_VIBRATION, MA_CTRL_DONE, MA_OPT_SAVECFG, MA_OPT_SAVECFG_GAME, @@ -269,6 +270,7 @@ static const struct { CE_INTVAL(volume_boost), CE_INTVAL(psx_clock), CE_INTVAL(new_dynarec_hacks), + CE_INTVAL(in_enable_vibration), }; static char *get_cd_label(void) @@ -973,7 +975,8 @@ static const char *men_in_type_sel[] = { 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[] = { @@ -984,6 +987,7 @@ 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), @@ -2044,6 +2048,7 @@ void menu_init(void) 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 } diff --git a/frontend/plat_dummy.c b/frontend/plat_dummy.c index 78a942b7..689fa3b4 100644 --- a/frontend/plat_dummy.c +++ b/frontend/plat_dummy.c @@ -71,3 +71,7 @@ int plat_get_bat_capacity(void) void plat_step_volume(int is_up) { } + +void plat_trigger_vibrate(void) +{ +} diff --git a/frontend/plat_omap.c b/frontend/plat_omap.c index 5474bda0..bee0912b 100644 --- a/frontend/plat_omap.c +++ b/frontend/plat_omap.c @@ -120,6 +120,10 @@ void plat_step_volume(int is_up) { } +void plat_trigger_vibrate(void) +{ +} + void plat_init(void) { const char *main_fb_name, *layer_fb_name; diff --git a/frontend/plat_pollux.c b/frontend/plat_pollux.c index a5e62f71..b8bd5a23 100644 --- a/frontend/plat_pollux.c +++ b/frontend/plat_pollux.c @@ -672,6 +672,97 @@ static const char * const caanoo_keys[KEY_MAX + 1] = { [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[] = { diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index eba09fb1..98d7e11d 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -33,6 +33,7 @@ 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; diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h index 914cbff8..4d59dc05 100644 --- a/frontend/plugin_lib.h +++ b/frontend/plugin_lib.h @@ -19,6 +19,7 @@ enum { }; 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; diff --git a/maemo/hildon.c b/maemo/hildon.c index f66d884d..a5f151ec 100644 --- a/maemo/hildon.c +++ b/maemo/hildon.c @@ -262,3 +262,6 @@ void plat_step_volume(int is_up) { } +void plat_trigger_vibrate(void) +{ +} diff --git a/plugins/dfinput/main.h b/plugins/dfinput/main.h index ee301656..34921704 100644 --- a/plugins/dfinput/main.h +++ b/plugins/dfinput/main.h @@ -24,3 +24,7 @@ extern long (*PAD2_readPort2)(PadDataS *pad); #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); diff --git a/plugins/dfinput/pad.c b/plugins/dfinput/pad.c index 90fde88d..ab55db0f 100644 --- a/plugins/dfinput/pad.c +++ b/plugins/dfinput/pad.c @@ -203,6 +203,11 @@ static void do_cmd2(unsigned char value) break; } break; + + case CMD_READ_DATA_AND_VIBRATE: + if (value == 1 && CurPad == 0 && in_enable_vibration) + plat_trigger_vibrate(); + break; } } -- 2.39.5