From: ksv1986 <ksv0x07c2@gmail.com>
Date: Sat, 29 Nov 2014 14:15:37 +0000 (+0300)
Subject: libretro: Add rumble support
X-Git-Tag: r20~21
X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e47706596441172d1cc3f203b8baa398cea3023;p=pcsx_rearmed.git

libretro: Add rumble support

Conflicts:
	frontend/libretro.c
---

diff --git a/frontend/libretro.c b/frontend/libretro.c
index 23c34ae5..47f07a63 100644
--- a/frontend/libretro.c
+++ b/frontend/libretro.c
@@ -33,6 +33,7 @@ static retro_input_poll_t input_poll_cb;
 static retro_input_state_t input_state_cb;
 static retro_environment_t environ_cb;
 static retro_audio_sample_batch_t audio_batch_cb;
+static struct retro_rumble_interface rumble;
 
 static void *vout_buf;
 static int vout_width, vout_height;
@@ -51,7 +52,7 @@ extern char McdDisable[2];
 int in_type1, in_type2;
 int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 };
 int in_keystate;
-int in_enable_vibration;
+int in_enable_vibration = 1;
 
 /* PSX max resolution is 640x512, but with enhancement it's 1024x512 */
 #define VOUT_MAX_WIDTH 1024
@@ -196,8 +197,10 @@ void pl_timing_prepare(int is_pal)
 	is_pal_mode = is_pal;
 }
 
-void plat_trigger_vibrate(int is_strong)
+void plat_trigger_vibrate(int pad, uint32_t low, uint32_t high)
 {
+    rumble.set_rumble_state(pad, RETRO_RUMBLE_STRONG, high << 8);
+    rumble.set_rumble_state(pad, RETRO_RUMBLE_WEAK, low ? 0xffff : 0x0);
 }
 
 void pl_update_gun(int *xn, int *yn, int *xres, int *yres, int *in)
@@ -238,11 +241,12 @@ void out_register_libretro(struct out_driver *drv)
 void retro_set_environment(retro_environment_t cb)
 {
    static const struct retro_variable vars[] = {
-      { "frameskip", "Frameskip; 0|1|2|3" },
-      { "region", "Region; Auto|NTSC|PAL" },
-      { "pad1type", "Pad 1 Type; standard|analog" },
+      { "pcsx_rearmed_frameskip", "Frameskip; 0|1|2|3" },
+      { "pcsx_rearmed_region", "Region; Auto|NTSC|PAL" },
+      { "pcsx_rearmed_pad1type", "Pad 1 Type; standard|analog" },
+      { "pcsx_rearmed_pad2type", "Pad 2 Type; standard|analog" },
 #ifndef DRC_DISABLE
-      { "rearmed_drc", "Dynamic recompiler; enabled|disabled" },
+      { "pcsx_rearmed_drc", "Dynamic recompiler; enabled|disabled" },
 #endif
 #ifdef __ARM_NEON__
       { "pcsx_rearmed_neon_interlace_enable", "Enable interlacing mode(s); disabled|enabled" },
@@ -947,13 +951,13 @@ static void update_variables(bool in_flight)
    struct retro_variable var;
    
    var.value = NULL;
-   var.key = "frameskip";
+   var.key = "pcsx_rearmed_frameskip";
 
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
       pl_rearmed_cbs.frameskip = atoi(var.value);
 
    var.value = NULL;
-   var.key = "region";
+   var.key = "pcsx_rearmed_region";
 
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
    {
@@ -967,7 +971,7 @@ static void update_variables(bool in_flight)
    }
 
    var.value = NULL;
-   var.key = "pad1type";
+   var.key = "pcsx_rearmed_pad1type";
 
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
    {
@@ -976,6 +980,16 @@ static void update_variables(bool in_flight)
          in_type1 = PSE_PAD_TYPE_ANALOGPAD;
    }
 
+   var.value = NULL;
+   var.key = "pcsx_rearmed_pad2type";
+
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+   {
+      in_type2 = PSE_PAD_TYPE_STANDARD;
+      if (strcmp(var.value, "analog") == 0)
+         in_type2 = PSE_PAD_TYPE_ANALOGPAD;
+   }
+
 #ifdef __ARM_NEON__
    var.value = "NULL";
    var.key = "pcsx_rearmed_neon_interlace_enable";
@@ -1024,7 +1038,7 @@ static void update_variables(bool in_flight)
 
 #ifndef DRC_DISABLE
    var.value = NULL;
-   var.key = "rearmed_drc";
+   var.key = "pcsx_rearmed_drc";
 
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
    {
@@ -1229,6 +1243,7 @@ void retro_init(void)
 
 	environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &vout_can_dupe);
 	environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control);
+	environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble);
 
 	/* Set how much slower PSX CPU runs * 100 (so that 200 is 2 times)
 	 * we have to do this because cache misses and some IO penalties
diff --git a/include/psemu_plugin_defs.h b/include/psemu_plugin_defs.h
index 3926ccd1..0805f4ae 100644
--- a/include/psemu_plugin_defs.h
+++ b/include/psemu_plugin_defs.h
@@ -205,7 +205,11 @@ typedef struct
 	// values are in range -128 - 127
 	unsigned char moveX, moveY;
 
-	unsigned char reserved[91];
+    uint8_t Vib[2];
+
+    volatile uint8_t VibF[2];
+
+    unsigned char reserved[87];
 
 } PadDataS;
 
diff --git a/plugins/dfinput/externals.h b/plugins/dfinput/externals.h
index 5419977a..042d9dcf 100644
--- a/plugins/dfinput/externals.h
+++ b/plugins/dfinput/externals.h
@@ -11,4 +11,4 @@ extern void pl_update_gun(int *xn, int *yn, int *xres, int *yres, int *in);
 
 /* vibration trigger to frontend */
 extern int in_enable_vibration;
-extern void plat_trigger_vibrate(int is_strong);
+extern void plat_trigger_vibrate(int pad, uint32_t low, uint32_t high);
diff --git a/plugins/dfinput/pad.c b/plugins/dfinput/pad.c
index 53a254a4..348bb8f3 100644
--- a/plugins/dfinput/pad.c
+++ b/plugins/dfinput/pad.c
@@ -203,22 +203,41 @@ 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(0);
-			break;
 	}
 }
 
 static void do_cmd3(unsigned char value)
 {
-	if (in_enable_vibration && CurCmd == CMD_READ_DATA_AND_VIBRATE && CurPad == 0) {
-		if (value >= 0xf0)
-			plat_trigger_vibrate(1);
-		else if (value > 0x40)
-			plat_trigger_vibrate(0);
-	}
+    int i;
+    switch (CurCmd) {
+        case CMD_READ_DATA_AND_VIBRATE:
+            if (!in_enable_vibration)
+                break;
+            if (padstate[CurPad].pad.controllerType != PSE_PAD_TYPE_ANALOGPAD)
+                break;
+
+            for (i = 0; i < 2; i++) {
+                if (padstate[CurPad].pad.Vib[i] == CurByte)
+                    padstate[CurPad].pad.VibF[i] = value;
+            }
+
+            plat_trigger_vibrate(CurPad,
+                                 padstate[CurPad].pad.VibF[0],
+                                 padstate[CurPad].pad.VibF[1]);
+            break;
+        case CMD_VIBRATION_TOGGLE:
+            for (i = 0; i < 2; i++) {
+                if (padstate[CurPad].pad.Vib[i] == CurByte)
+                    buf[CurByte] = 0;
+            }
+            if (value < 2) {
+                padstate[CurPad].pad.Vib[value] = CurByte;
+                if((padstate[CurPad].PadID & 0x0f) < (CurByte - 1) / 2) {
+                    padstate[CurPad].PadID = (padstate[CurPad].PadID & 0xf0) + (CurByte - 1) / 2;
+                }
+            }
+            break;
+    }
 }
 
 #if 0
@@ -233,9 +252,7 @@ unsigned char PADpoll(unsigned char value) {
 #endif
 
 unsigned char PADpoll_pad(unsigned char value) {
-
-	switch (CurByte) {
-	case 0:
+    if (CurByte == 0) {
 		CurCmd = value;
 		CurByte++;
 
@@ -244,16 +261,15 @@ unsigned char PADpoll_pad(unsigned char value) {
 			CurCmd = CMD_READ_DATA_AND_VIBRATE;
 
 		return do_cmd();
-	case 2:
+    }
+
+    if (CurByte >= CmdLen)
+        return 0xff;	// verified
+
+    if (CurByte == 2)
 		do_cmd2(value);
-		break;
-	case 3:
-		do_cmd3(value);
-		break;
-	}
 
-	if (CurByte >= CmdLen)
-		return 0xff;	// verified
+    do_cmd3(value);
 
 	return buf[CurByte++];
 }