#pragma once #include "../GPU/gpu_types.hpp" #include "raw_controller.hpp" namespace JabyEngine { namespace Periphery { class GenericController : public RawController { public: struct Rumble { static constexpr uint8_t LargeMotorThreshold = 0x60; }; enum struct Button : uint16_t { L2 = static_cast(GenericButton::D0), R2 = static_cast(GenericButton::D1), L1 = static_cast(GenericButton::D2), R1 = static_cast(GenericButton::D3), Triangle = static_cast(GenericButton::D4), Circle = static_cast(GenericButton::D5), Cross = static_cast(GenericButton::D6), Square = static_cast(GenericButton::D7), SEL = static_cast(GenericButton::D8), ST = static_cast(GenericButton::D11), Up = static_cast(GenericButton::D12), Right = static_cast(GenericButton::D13), Down = static_cast(GenericButton::D14), Left = static_cast(GenericButton::D15) }; void set_digital_rumble() { RawController::header.rumble0 = 0x1; RawController::header.rumble1 = 0x7F; } void set_analog_rumble(uint8_t largeMotor, bool smallMotor) { RawController::header.rumble0 = smallMotor ? 0x1 : 0x0; RawController::header.rumble1 = largeMotor; } void stopRumble() { RawController::header.rumble0 = 0x0; RawController::header.rumble1 = 0x0; } bool is_small_rumble() const { return static_cast(RawController::header.rumble0); } uint8_t get_large_rumble() const { return RawController::header.rumble1; } bool is_connected() const { return RawController::header.state != RawController::State::Disconnected; } bool is_useable() const { const auto type = RawController::get_type(); return ((RawController::header.state == RawController::State::Stable) && (type == ControllerType::Controller || type == ControllerType::DualShock)); } }; class AnalogeController : public GenericController { public: enum struct Button : uint16_t { L2 = static_cast(GenericButton::D0), R2 = static_cast(GenericButton::D1), L1 = static_cast(GenericButton::D2), R1 = static_cast(GenericButton::D3), Triangle = static_cast(GenericButton::D4), Circle = static_cast(GenericButton::D5), Cross = static_cast(GenericButton::D6), Square = static_cast(GenericButton::D7), SEL = static_cast(GenericButton::D8), L3 = static_cast(GenericButton::D9), R3 = static_cast(GenericButton::D10), ST = static_cast(GenericButton::D11), Up = static_cast(GenericButton::D12), Right = static_cast(GenericButton::D13), Down = static_cast(GenericButton::D14), Left = static_cast(GenericButton::D15) }; private: uint8_t read_special_byte(size_t idx) const { return reinterpret_cast(this->special)[idx]; } public: GPU::PositionI16 get_right_stick_pos() const { const uint8_t joy_x = AnalogeController::read_special_byte(0); const uint8_t joy_y = AnalogeController::read_special_byte(1); return GPU::PositionI16::create(joy_x - 0x80, joy_y - 0x80); } GPU::PositionI16 get_left_stick_pos() const { const uint8_t joy_x = AnalogeController::read_special_byte(2); const uint8_t joy_y = AnalogeController::read_special_byte(3); return GPU::PositionI16::create(joy_x - 0x80, joy_y - 0x80); } }; using GenericButtonState = GenericController::ButtonState; } }