diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 0f0d7401..e80666bf 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,7 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "platformio.platformio-ide" - ] -} +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} diff --git a/HAL/pico/include/config_defaults.hpp b/HAL/pico/include/config_defaults.hpp index 9f74b0dd..96c9f971 100644 --- a/HAL/pico/include/config_defaults.hpp +++ b/HAL/pico/include/config_defaults.hpp @@ -7,9 +7,9 @@ // clang-format off const Config default_config = { - .game_mode_configs_count = 6, + .game_mode_configs_count = 7, .game_mode_configs = { - GameModeConfig { + GameModeConfig { .mode_id = MODE_MELEE, .socd_pairs_count = 4, .socd_pairs = { @@ -22,7 +22,7 @@ const Config default_config = { .activation_binding_count = 3, .activation_binding = { BTN_LT1, BTN_MB1, BTN_LF4 }, }, - GameModeConfig { + GameModeConfig { .mode_id = MODE_PROJECT_M, .socd_pairs_count = 4, .socd_pairs = { @@ -75,6 +75,19 @@ const Config default_config = { .activation_binding_count = 3, .activation_binding = { BTN_LT1, BTN_MB1, BTN_RF1 }, }, + GameModeConfig { + .mode_id = MODE_RIVALS_2, + .socd_pairs_count = 4, + .socd_pairs = { + SocdPair { .button_dir1 = BTN_LF3, .button_dir2 = BTN_LF1, .socd_type = SOCD_2IP_NO_REAC }, + SocdPair { .button_dir1 = BTN_LF2, .button_dir2 = BTN_RF4, .socd_type = SOCD_2IP_NO_REAC }, + SocdPair { .button_dir1 = BTN_RT3, .button_dir2 = BTN_RT5, .socd_type = SOCD_2IP_NO_REAC }, + SocdPair { .button_dir1 = BTN_RT2, .button_dir2 = BTN_RT4, .socd_type = SOCD_2IP_NO_REAC }, + }, + .button_remapping_count = 0, + .activation_binding_count = 3, + .activation_binding = { BTN_LT1, BTN_MB1, BTN_RF5 }, + }, GameModeConfig { .mode_id = MODE_KEYBOARD, .socd_pairs_count = 2, @@ -177,4 +190,4 @@ const Config default_config = { // clang-format on -#endif \ No newline at end of file +#endif diff --git a/config/pico/config.cpp b/config/pico/config.cpp index 68a5c754..2249f2ef 100644 --- a/config/pico/config.cpp +++ b/config/pico/config.cpp @@ -16,33 +16,33 @@ Config config = default_config; GpioButtonMapping button_mappings[] = { - {BTN_LF1, 2 }, - { BTN_LF2, 3 }, - { BTN_LF3, 4 }, - { BTN_LF4, 5 }, - - { BTN_LT1, 6 }, - { BTN_LT2, 7 }, - - { BTN_MB1, 0 }, - { BTN_MB2, 10}, - { BTN_MB3, 11}, - - { BTN_RT1, 14}, - { BTN_RT2, 15}, - { BTN_RT3, 13}, - { BTN_RT4, 12}, - { BTN_RT5, 16}, - - { BTN_RF1, 26}, - { BTN_RF2, 21}, - { BTN_RF3, 19}, - { BTN_RF4, 17}, - - { BTN_RF5, 27}, - { BTN_RF6, 22}, - { BTN_RF7, 20}, - { BTN_RF8, 18}, + { BTN_LF1, 2 }, + { BTN_LF2, 3 }, + { BTN_LF3, 4 }, + { BTN_LF4, 5 }, + + { BTN_LT1, 6 }, + { BTN_LT2, 7 }, + + { BTN_MB1, 0 }, + { BTN_MB2, 10 }, + { BTN_MB3, 11 }, + + { BTN_RT1, 14 }, + { BTN_RT2, 15 }, + { BTN_RT3, 13 }, + { BTN_RT4, 12 }, + { BTN_RT5, 16 }, + + { BTN_RF1, 26 }, + { BTN_RF2, 21 }, + { BTN_RF3, 19 }, + { BTN_RF4, 17 }, + + { BTN_RF5, 27 }, + { BTN_RF6, 22 }, + { BTN_RF7, 20 }, + { BTN_RF8, 18 }, }; const size_t button_count = sizeof(button_mappings) / sizeof(GpioButtonMapping); @@ -115,4 +115,4 @@ void loop1() { if (backends != nullptr) { gpio_input.UpdateInputs(backends[0]->GetInputs()); } -} +} \ No newline at end of file diff --git a/include/core/config_utils.hpp b/include/core/config_utils.hpp index 31b95581..0812c516 100644 --- a/include/core/config_utils.hpp +++ b/include/core/config_utils.hpp @@ -41,6 +41,8 @@ constexpr const char *gamemode_name(GameModeId mode_id) { return "FGC"; case MODE_RIVALS_OF_AETHER: return "Rivals"; + case MODE_RIVALS_2: + return "Rivals 2"; case MODE_KEYBOARD: return "Keyboard"; default: @@ -88,4 +90,4 @@ constexpr const char *socd_name(SocdType socd_type) { } } -#endif \ No newline at end of file +#endif diff --git a/include/modes/Rivals2.hpp b/include/modes/Rivals2.hpp new file mode 100644 index 00000000..5ccbbad3 --- /dev/null +++ b/include/modes/Rivals2.hpp @@ -0,0 +1,18 @@ +#ifndef _MODES_RIVALS_2_HPP +#define _MODES_RIVALS_2_HPP + +#include "core/ControllerMode.hpp" +#include "core/state.hpp" + +#include //this was not here, but doesn't seem to matter if I remove it from Melee20Button.hpp anyway + +class Rivals2 : public ControllerMode { + public: + Rivals2(); + + private: + void UpdateDigitalOutputs(const InputState &inputs, OutputState &outputs); + void UpdateAnalogOutputs(const InputState &inputs, OutputState &outputs); +}; + +#endif diff --git a/platformio.ini b/platformio.ini index 2a5baa73..0628e8e2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -22,7 +22,7 @@ custom_nanopb_options = --error-on-unmatched lib_deps = nanopb/Nanopb@^0.4.8 - https://github.com/JonnyHaystack/HayBox-proto#5b2bb5d + https://github.com/JonnyHaystack/HayBox-proto#bbd0862 [avr_base] platform = atmelavr diff --git a/src/core/mode_selection.cpp b/src/core/mode_selection.cpp index 257b9da2..81a7e1d0 100644 --- a/src/core/mode_selection.cpp +++ b/src/core/mode_selection.cpp @@ -6,6 +6,7 @@ #include "modes/FgcMode.hpp" #include "modes/Melee20Button.hpp" #include "modes/ProjectM.hpp" +#include "modes/Rivals2.hpp" #include "modes/RivalsOfAether.hpp" #include "modes/Ultimate.hpp" #include "util/state_util.hpp" @@ -17,6 +18,7 @@ ProjectM projectm_mode; Ultimate ultimate_mode; FgcMode fgc_mode; RivalsOfAether rivals_mode; +Rivals2 rivals2_mode; CustomKeyboardMode keyboard_mode; CustomControllerMode custom_mode; @@ -68,6 +70,10 @@ void set_mode(CommunicationBackend *backend, GameModeConfig &mode_config, Config rivals_mode.SetConfig(mode_config); set_mode(backend, &rivals_mode); break; + case MODE_RIVALS_2: + rivals2_mode.SetConfig(mode_config); + set_mode(backend, &rivals2_mode); + break; case MODE_KEYBOARD: if (backend->BackendId() != COMMS_BACKEND_DINPUT || mode_config.keyboard_mode_config < 1 || @@ -137,4 +143,4 @@ void setup_mode_activation_bindings(const GameModeConfig *mode_configs, size_t m mode_configs[i].activation_binding_count ); } -} \ No newline at end of file +} diff --git a/src/modes/Rivals2.cpp b/src/modes/Rivals2.cpp new file mode 100644 index 00000000..eb8eb483 --- /dev/null +++ b/src/modes/Rivals2.cpp @@ -0,0 +1,260 @@ +#include "modes/Rivals2.hpp" + +#define ANALOG_STICK_MIN 0 +#define ANALOG_STICK_NEUTRAL 128 +#define ANALOG_STICK_MAX 255 + +bool input_persist; // for angled tilts +int timer = 0; // for angled tilts + +Rivals2::Rivals2() : ControllerMode() {} + +void Rivals2::UpdateDigitalOutputs(const InputState &inputs, OutputState &outputs) { + outputs.a = inputs.rt1; + outputs.b = inputs.rf1; + outputs.x = inputs.rf2; + outputs.y = inputs.rf6; + outputs.buttonR = inputs.rf3; + if (inputs.nunchuk_connected) { + // Lightshield with C button. + if (inputs.nunchuk_c) { + outputs.triggerLAnalog = 49; + } + outputs.triggerLDigital = inputs.nunchuk_z; + } else { + outputs.triggerLDigital = inputs.lf4; + } + outputs.triggerRDigital = inputs.rf5; + outputs.start = inputs.mb1; + outputs.select = inputs.mb3; + outputs.home = inputs.mb2; + outputs.leftStickClick = inputs.rf7; + outputs.buttonL = inputs.rf8; //changed from rightStickClick to buttonL + //only because buttonL is a default mapping in Rivals 2 (doesn't really matter) + + // Activate D-Pad layer by holding Mod X + Mod Y. + if (inputs.lt1 && inputs.lt2) { + outputs.dpadUp = inputs.rt4; + outputs.dpadDown = inputs.rt2; + outputs.dpadLeft = inputs.rt3; + outputs.dpadRight = inputs.rt5; + } +} + +void Rivals2::UpdateAnalogOutputs(const InputState &inputs, OutputState &outputs) { + // Coordinate calculations to make modifier handling simpler. + UpdateDirections( + inputs.lf3, // Left + inputs.lf1, // Right + inputs.lf2, // Down + inputs.rf4, // Up + inputs.rt3, // C-Left + inputs.rt5, // C-Right + inputs.rt2, // C-Down + inputs.rt4, // C-Up + ANALOG_STICK_MIN, + ANALOG_STICK_NEUTRAL, + ANALOG_STICK_MAX, + outputs + ); + + bool shield_button_pressed = inputs.lf4 || inputs.rf5; // if L or R are pressed + + if (directions.diagonal && !shield_button_pressed) { //added this conditional to give joystick accurate diagonals rather than (+/- 1.2, 1.2) should be (0.87~, 0.87~) + outputs.leftStickX = 128 + (directions.x * 92); // 92 (0.78 in-game), reduced below 0.8 to allow crouch tilts/crouch turn-around tilts + outputs.leftStickY = 128 + (directions.y * 96);//Y value 0.83. >0.8 allows fast fall + } + + if (directions.diagonal && shield_button_pressed) { + outputs.leftStickX = 128 + (directions.x * 92); // (0.77~, 0.77~) to prevent spot dodging when pressing diagonal on the ground + outputs.leftStickY = 128 + (directions.y * 92); + } + + // For MX Angled Tilts when input_persist is true + //(x, y), (69, 53), (~0.506, ~0.31) [coords, code_values, in-game values] + if (input_persist) { //input_persist becomes true if ModX + diagonal + A + timer++; + outputs.leftStickX = 128 + (directions.x * 69); + outputs.leftStickY = 128 + (directions.y * 53); + } + + if (timer == 150) { // 150 has a 90% success rate on pico + timer = 0; + input_persist = false; + } + + + + if (inputs.lt1) { //if ModX is held + if (directions.horizontal) { + outputs.leftStickX = 128 + (directions.x * 76); //76 gives 0.58~ in-game for a medium speed walk. will also do tilts + } + + if(directions.vertical) { + outputs.leftStickY = 128 + (directions.y * 53); // 48 (0.31~ in-game), 0.3 allows tilts and shield drop + } + + if (directions.diagonal && shield_button_pressed) { //for max-length diagonal wavedash while holding ModX + outputs.leftStickX = 128 + (directions.x * 120); + outputs.leftStickY = 128 + (directions.y * 42); + } + + if (directions.diagonal && !shield_button_pressed) { + /* 100% Magnitude UpB when holding B */ + if (inputs.rf1 && !inputs.rf3) { + // (x, y), (123, 51), (1.14~, 0.29~) [coords, code_values, in-game values] + outputs.leftStickX = 128 + (directions.x * 123); + outputs.leftStickY = 128 + (directions.y * 51); + // (x, y), (120, 61), (1.1~, 0.41~) [coords, code_values, in-game values] + if (inputs.rt2) { //C-Down + outputs.leftStickX = 128 + (directions.x * 120); + outputs.leftStickY = 128 + (directions.y * 61); + } + // (x, y), (115, 69), (1.04~, 0.51~) [coords, code_values, in-game values] + if (inputs.rt3) { //C-Left + outputs.leftStickX = 128 + (directions.x * 115); + outputs.leftStickY = 128 + (directions.y * 69); + } + // (x, y), (110, 78), (0.98~, 0.61~) [coords, code_values, in-game values] + if (inputs.rt4) { //C-Up + outputs.leftStickX = 128 + (directions.x * 110); + outputs.leftStickY = 128 + (directions.y * 78); + } + // (x, y), (103, 87), (0.9~, 0.71~) [coords, code_values, in-game values] + if (inputs.rt5) { //C-Right + outputs.leftStickX = 128 + (directions.x * 103); + outputs.leftStickY = 128 + (directions.y * 87); + } + } + /* 60% Magnitude UpB when not holding B nor Z*/ + if (!inputs.rf3 && !inputs.rf1 && !input_persist) { + // (x, y), (68, 42), (~0.49, ~0.188) [coords, code_values, in-game values] + outputs.leftStickX = 128 + (directions.x * 68); + outputs.leftStickY = 128 + (directions.y * 42); + // (x, y), (71, 47), (~0.52, ~0.24) [coords, code_values, in-game values] + if (inputs.rt2) { //C-Down + outputs.leftStickX = 128 + (directions.x * 71); + outputs.leftStickY = 128 + (directions.y * 47); + } + // (x, y), (71, 51), (~0.52, 0.29~) [coords, code_values, in-game values] + if (inputs.rt3) { //C-Left + outputs.leftStickX = 128 + (directions.x * 71); + outputs.leftStickY = 128 + (directions.y * 51); + } + // (x, y), (69, 55), (~0.51, ~0.34) [coords, code_values, in-game values] + if (inputs.rt4) { //C-Up + outputs.leftStickX = 128 + (directions.x * 69); + outputs.leftStickY = 128 + (directions.y * 55); + } + // (x, y), (64, 60), (, ~0.38) [coords, code_values, in-game values] + if (inputs.rt5) { //C-Right + outputs.leftStickX = 128 + (directions.x * 64); + outputs.leftStickY = 128 + (directions.y * 60); + } + } + /* Shortest UpB when holding Z*/ + if (inputs.rf3) { + // (x, y), (53, 68), (~0.31, ~0.188) [coords, code_values, in-game values] + outputs.leftStickX = 128 + (directions.x * 53); + outputs.leftStickY = 128 + (directions.y * 42); + } + /*ModX Angled Tilts*/ + if (inputs.rt1) { + input_persist = true; + timer = 0; + outputs.leftStickX = 128 + (directions.x * 69); + outputs.leftStickY = 128 + (directions.y * 53); + } + } + } + + + if (inputs.lt2) { // if ModY is held + if (directions.horizontal) { + outputs.leftStickX = 128 + (directions.x * 53); //53 equates to 0.318~ in-game. 0.3 is min to achieve a walk + } + + if(directions.vertical) { + outputs.leftStickY = 128 + (directions.y * 90); // 0.75~ in-game. will shield drop and tap jump; will not fast fall + } + + if (directions.diagonal && !shield_button_pressed) { + /* 100% Magnitude UpB when holding B*/ + if (inputs.rf1 && !inputs.rf3) { + // (x, y), (51, 123), (~0.29, ~1.14) [coords, code_values, in-game values] + outputs.leftStickX = 128 + (directions.x * 51); + outputs.leftStickY = 128 + (directions.y * 123); + // (x, y), (61, 120), (~0.41, ~1.1) [coords, code_values, in-game values] + if (inputs.rt2) { //C-Down + outputs.leftStickX = 128 + (directions.x * 61); + outputs.leftStickY = 128 + (directions.y * 120); + } + // (x, y), (69, 115), (~0.51, 1.04~) [coords, code_values, in-game values] + if (inputs.rt3) { //C-Left + outputs.leftStickX = 128 + (directions.x * 69); + outputs.leftStickY = 128 + (directions.y * 115); + } + // (x, y), (78, 110), (~0.61, 0.98~) [coords, code_values, in-game values] + if (inputs.rt4) { //C-Up + outputs.leftStickX = 128 + (directions.x * 78); + outputs.leftStickY = 128 + (directions.y * 110); + } + // (x, y), (87, 103), (~0.71, 0.9~) [coords, code_values, in-game values] + if (inputs.rt5) { //C-Right + outputs.leftStickX = 128 + (directions.x * 87); + outputs.leftStickY = 128 + (directions.y * 103); + } + } + /* 60% Magnitude UpB when not holding B nor Z*/ + if (!inputs.rf3 && !inputs.rf1) { + // (x, y), (42, 68), (~0.188, ~0.49) [coords, code_values, in-game values] + outputs.leftStickX = 128 + (directions.x * 42); + outputs.leftStickY = 128 + (directions.y * 68); + // (x, y), (47, 71), (~0.24, ~0.52) [coords, code_values, in-game values] + if (inputs.rt2) { //C-Down + outputs.leftStickX = 128 + (directions.x * 47); + outputs.leftStickY = 128 + (directions.y * 71); + } + // (x, y), (51, 71), (~0.29, ~0.52) [coords, code_values, in-game values] + if (inputs.rt3) { //C-Left + outputs.leftStickX = 128 + (directions.x * 51); + outputs.leftStickY = 128 + (directions.y * 71); + } + // (x, y), (55, 69), (~0.34, ~0.51) [coords, code_values, in-game values] + if (inputs.rt4) { //C-Up + outputs.leftStickX = 128 + (directions.x * 55); + outputs.leftStickY = 128 + (directions.y * 69); + } + // (x, y), (60, 64), (~0.38, ~0.) [coords, code_values, in-game values] + if (inputs.rt5) { //C-Right + outputs.leftStickX = 128 + (directions.x * 60); + outputs.leftStickY = 128 + (directions.y * 64); + } + } + /* Shortest UpB when holding Z*/ + if (inputs.rf3) { + // (x, y), (42, 53), (~0.188, ~0.31) [coords, code_values, in-game values] + outputs.leftStickX = 128 + (directions.x * 42); + outputs.leftStickY = 128 + (directions.y * 53); + } + /* For buffered turnaround up-tilt/down-tilt with ModY + Diagonal */ + if (inputs.rt1) { + outputs.leftStickX = 128 + (directions.x * 69); + outputs.leftStickY = 128 + (directions.y * 89); + } + } + } + + + // Shut off C-stick when using D-Pad layer. + if (inputs.lt1 && inputs.lt2) { + outputs.rightStickX = 128; + outputs.rightStickY = 128; + } + + // Nunchuk overrides left stick. + if (inputs.nunchuk_connected) { + outputs.leftStickX = inputs.nunchuk_x; + outputs.leftStickY = inputs.nunchuk_y; + } +}