Run SysReset() only from retro_run, causes retroarch to freeze...
[pcsx_rearmed.git] / frontend / libretro.c
index f9accf2..ec0065d 100644 (file)
@@ -57,7 +57,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 retro_set_rumble_state_t rumble_cb;
 static struct retro_log_callback logging;
 static retro_log_printf_t log_cb;
 
@@ -430,10 +430,13 @@ void pl_timing_prepare(int is_pal)
 
 void plat_trigger_vibrate(int pad, int low, int high)
 {
-       if(in_enable_vibration)
+       if (!rumble_cb)
+               return;
+
+       if (in_enable_vibration)
        {
-       rumble.set_rumble_state(pad, RETRO_RUMBLE_STRONG, high << 8);
-       rumble.set_rumble_state(pad, RETRO_RUMBLE_WEAK, low ? 0xffff : 0x0);
+               rumble_cb(pad, RETRO_RUMBLE_STRONG, high << 8);
+               rumble_cb(pad, RETRO_RUMBLE_WEAK, low ? 0xffff : 0x0);
     }
 }
 
@@ -464,14 +467,14 @@ void retro_set_environment(retro_environment_t cb)
       { "pcsx_rearmed_frameskip", "Frameskip; 0|1|2|3" },
       { "pcsx_rearmed_region", "Region; auto|NTSC|PAL" },
       { "pcsx_rearmed_memcard2", "Enable second memory card; disabled|enabled" },
-      { "pcsx_rearmed_pad1type", "Pad 1 Type; default|none|standard|analog|negcon" },
-      { "pcsx_rearmed_pad2type", "Pad 2 Type; default|none|standard|analog|negcon" },
-      { "pcsx_rearmed_pad3type", "Pad 3 Type; default|none|standard|analog|negcon" },
-      { "pcsx_rearmed_pad4type", "Pad 4 Type; default|none|standard|analog|negcon" },
-      { "pcsx_rearmed_pad5type", "Pad 5 Type; default|none|standard|analog|negcon" },
-      { "pcsx_rearmed_pad6type", "Pad 6 Type; default|none|standard|analog|negcon" },
-      { "pcsx_rearmed_pad7type", "Pad 7 Type; default|none|standard|analog|negcon" },
-      { "pcsx_rearmed_pad8type", "Pad 8 Type; default|none|standard|analog|negcon" },
+      { "pcsx_rearmed_pad1type", "Pad 1 Type; default|none|standard|analog|dualshock|negcon" },
+      { "pcsx_rearmed_pad2type", "Pad 2 Type; default|none|standard|analog|dualshock|negcon" },
+      { "pcsx_rearmed_pad3type", "Pad 3 Type; default|none|standard|analog|dualshock|negcon" },
+      { "pcsx_rearmed_pad4type", "Pad 4 Type; default|none|standard|analog|dualshock|negcon" },
+      { "pcsx_rearmed_pad5type", "Pad 5 Type; default|none|standard|analog|dualshock|negcon" },
+      { "pcsx_rearmed_pad6type", "Pad 6 Type; default|none|standard|analog|dualshock|negcon" },
+      { "pcsx_rearmed_pad7type", "Pad 7 Type; default|none|standard|analog|dualshock|negcon" },
+      { "pcsx_rearmed_pad8type", "Pad 8 Type; default|none|standard|analog|dualshock|negcon" },
       { "pcsx_rearmed_multitap1", "Multitap 1; auto|disabled|enabled" },
       { "pcsx_rearmed_multitap2", "Multitap 2; auto|disabled|enabled" },
       { "pcsx_rearmed_negcon_deadzone", "NegCon Twist Deadzone (percent); 0|5|10|15|20|25|30" },
@@ -565,6 +568,8 @@ static void update_controller_port_variable(unsigned port)
                if (strcmp(var.value, "standard") == 0)
                        in_type[port] = PSE_PAD_TYPE_STANDARD;
                else if (strcmp(var.value, "analog") == 0)
+                       in_type[port] = PSE_PAD_TYPE_ANALOGJOY;
+               else if (strcmp(var.value, "dualshock") == 0)
                        in_type[port] = PSE_PAD_TYPE_ANALOGPAD;
                else if (strcmp(var.value, "negcon") == 0)
                        in_type[port] = PSE_PAD_TYPE_NEGCON;
@@ -1284,7 +1289,10 @@ bool retro_load_game(const struct retro_game_info *info)
                return false;
        }
 
-       SysReset();
+       /* TODO: Calling SysReset() outside retro_run for some system
+        * causes RetroArch to freeze, e.g Ludo */
+       //SysReset();
+       rebootemu = 1;
 
        if (LoadCdrom() == -1) {
                log_cb(RETRO_LOG_INFO, "could not load CD\n");
@@ -1630,7 +1638,10 @@ void retro_run(void)
        // reset all keystate, query libretro for keystate
        int j;
        int lsx;
+       int rsy;
        float negcon_twist_amplitude;
+       int negcon_i_rs;
+       int negcon_ii_rs;
        for(i = 0; i < PORTS_NUMBER; i++) {
                in_keystate[i] = 0;
 
@@ -1706,15 +1717,48 @@ void retro_run(void)
                        }
                        // >> Convert to final 'in_analog' integer value [0,255]
                        in_analog_right[i][0] = MAX(MIN((int)(negcon_twist_amplitude * 128.0f) + 128, 255), 0);
-                       // > NeGcon I
+                       // > NeGcon I + II
+                       // >> Handle right analog stick vertical axis mapping...
+                       //    - Up (-Y) == accelerate == neGcon I
+                       //    - Down (+Y) == brake == neGcon II
+                       negcon_i_rs = 0;
+                       negcon_ii_rs = 0;
+                       rsy = input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y);
+                       if (rsy >= 0){
+                               // Account for deadzone
+                               // (Note: have never encountered a gamepad with significant differences
+                               // in deadzone between left/right analog sticks, so use the regular 'twist'
+                               // deadzone here)
+                               if (rsy > negcon_deadzone){
+                                       rsy = rsy - negcon_deadzone;
+                               } else {
+                                       rsy = 0;
+                               }
+                               // Convert to 'in_analog' integer value [0,255]
+                               negcon_ii_rs = MIN((int)(((float)rsy / (float)(NEGCON_RANGE - negcon_deadzone)) * 255.0f), 255);
+                       } else {
+                               if (rsy < -negcon_deadzone){
+                                       rsy = -1 * (rsy + negcon_deadzone);
+                               } else {
+                                       rsy = 0;
+                               }
+                               negcon_i_rs = MIN((int)(((float)rsy / (float)(NEGCON_RANGE - negcon_deadzone)) * 255.0f), 255);
+                       }
+                       // >> NeGcon I
                        in_analog_right[i][1] = MAX(
-                               get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_R2),
-                               get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_B)
+                               MAX(
+                                       get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_R2),
+                                       get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_B)
+                               ),
+                               negcon_i_rs
                        );
-                       // > NeGcon II
+                       // >> NeGcon II
                        in_analog_left[i][0] = MAX(
-                               get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_L2),
-                               get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_Y)
+                               MAX(
+                                       get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_L2),
+                                       get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_Y)
+                               ),
+                               negcon_ii_rs
                        );
                        // > NeGcon L
                        in_analog_left[i][1] = get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_L);
@@ -1728,7 +1772,7 @@ void retro_run(void)
                                }
                        }
                        // Query analog inputs
-                       if (in_type[i] == PSE_PAD_TYPE_ANALOGPAD)
+                       if (in_type[i] == PSE_PAD_TYPE_ANALOGJOY || in_type[i] == PSE_PAD_TYPE_ANALOGPAD)
                        {
                                in_analog_left[i][0] = MIN((input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 255) + 128, 255);
                                in_analog_left[i][1] = MIN((input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 255) + 128, 255);
@@ -1845,6 +1889,7 @@ static int init_memcards(void)
 
 void retro_init(void)
 {
+       struct retro_rumble_interface rumble;
        const char *bios[] = {
                "SCPH101", "SCPH7001", "SCPH5501", "SCPH1001",
                "scph101", "scph7001", "scph5501", "scph1001"
@@ -1924,7 +1969,10 @@ 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);
+
+       rumble_cb = NULL;
+       if (environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble))
+               rumble_cb = rumble.set_rumble_state;
 
        /* 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