add vibration support for Caanoo
authornotaz <notasas@gmail.com>
Fri, 9 Dec 2011 16:35:09 +0000 (18:35 +0200)
committernotaz <notasas@gmail.com>
Sat, 10 Dec 2011 21:10:37 +0000 (23:10 +0200)
frontend/menu.c
frontend/plat_dummy.c
frontend/plat_omap.c
frontend/plat_pollux.c
frontend/plugin_lib.c
frontend/plugin_lib.h
maemo/hildon.c
plugins/dfinput/main.h
plugins/dfinput/pad.c

index 53f296a..f5d0415 100644 (file)
@@ -58,6 +58,7 @@ typedef enum
        MA_CTRL_DEV_NEXT,
        MA_CTRL_NUBS_BTNS,
        MA_CTRL_DEADZONE,
        MA_CTRL_DEV_NEXT,
        MA_CTRL_NUBS_BTNS,
        MA_CTRL_DEADZONE,
+       MA_CTRL_VIBRATION,
        MA_CTRL_DONE,
        MA_OPT_SAVECFG,
        MA_OPT_SAVECFG_GAME,
        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(volume_boost),
        CE_INTVAL(psx_clock),
        CE_INTVAL(new_dynarec_hacks),
+       CE_INTVAL(in_enable_vibration),
 };
 
 static char *get_cd_label(void)
 };
 
 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.";
        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[] =
 {
 
 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_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),
        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_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
 }
        me_enable(e_menu_keyconfig, MA_CTRL_DEADZONE, 0);
 #endif
 }
index 78a942b..689fa3b 100644 (file)
@@ -71,3 +71,7 @@ int plat_get_bat_capacity(void)
 void plat_step_volume(int is_up)
 {
 }
 void plat_step_volume(int is_up)
 {
 }
+
+void plat_trigger_vibrate(void)
+{
+}
index 5474bda..bee0912 100644 (file)
@@ -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;
 void plat_init(void)
 {
        const char *main_fb_name, *layer_fb_name;
index a5e62f7..b8bd5a2 100644 (file)
@@ -672,6 +672,97 @@ static const char * const caanoo_keys[KEY_MAX + 1] = {
        [BTN_BASE5]     = "Push",
 };
 
        [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[] =
 {
 /* Wiz stuff */
 struct in_default_bind in_gp2x_defbinds[] =
 {
index eba09fb..98d7e11 100644 (file)
@@ -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_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;
 int pl_flip_cnt;
 void *tsdev;
 void *pl_vout_buf;
index 914cbff..4d59dc0 100644 (file)
@@ -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_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 in_update_analogs(void);
 
 extern void *pl_vout_buf;
index f66d884..a5f151e 100644 (file)
@@ -262,3 +262,6 @@ void plat_step_volume(int is_up)
 {
 }
 
 {
 }
 
+void plat_trigger_vibrate(void)
+{
+}
index ee30165..3492170 100644 (file)
@@ -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);
 #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);
index 90fde88..ab55db0 100644 (file)
@@ -203,6 +203,11 @@ static void do_cmd2(unsigned char value)
                                        break;
                        }
                        break;
                                        break;
                        }
                        break;
+
+               case CMD_READ_DATA_AND_VIBRATE:
+                       if (value == 1 && CurPad == 0 && in_enable_vibration)
+                               plat_trigger_vibrate();
+                       break;
        }
 }
 
        }
 }