justifier.h (2582B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "controller.h" 7 #include "timing_event.h" 8 9 #include <memory> 10 11 class TimingEvent; 12 13 class Justifier final : public Controller 14 { 15 public: 16 enum class Binding : u8 17 { 18 Trigger = 0, 19 Start = 1, 20 Back = 2, 21 ShootOffscreen = 3, 22 ButtonCount = 4, 23 24 RelativeLeft = 4, 25 RelativeRight = 5, 26 RelativeUp = 6, 27 RelativeDown = 7, 28 BindingCount = 8, 29 }; 30 31 static const Controller::ControllerInfo INFO; 32 33 Justifier(u32 index); 34 ~Justifier() override; 35 36 static std::unique_ptr<Justifier> Create(u32 index); 37 38 ControllerType GetType() const override; 39 40 void Reset() override; 41 bool DoState(StateWrapper& sw, bool apply_input_state) override; 42 43 void LoadSettings(SettingsInterface& si, const char* section, bool initial) override; 44 45 float GetBindState(u32 index) const override; 46 void SetBindState(u32 index, float value) override; 47 48 void ResetTransferState() override; 49 bool Transfer(const u8 data_in, u8* data_out) override; 50 51 private: 52 bool IsTriggerPressed() const; 53 void UpdatePosition(); 54 void UpdateIRQEvent(); 55 void IRQEvent(); 56 57 std::pair<float, float> GetAbsolutePositionFromRelativeAxes() const; 58 bool CanUseSoftwareCursor() const; 59 u32 GetSoftwarePointerIndex() const; 60 void UpdateSoftwarePointerPosition(); 61 62 enum class TransferState : u8 63 { 64 Idle, 65 IDMSB, 66 ButtonsLSB, 67 ButtonsMSB, 68 XLSB, 69 XMSB, 70 YLSB, 71 YMSB 72 }; 73 74 static constexpr s8 DEFAULT_FIRST_LINE_OFFSET = -12; 75 static constexpr s8 DEFAULT_LAST_LINE_OFFSET = -6; 76 static constexpr s16 DEFAULT_TICK_OFFSET = 50; 77 static constexpr u8 DEFAULT_OFFSCREEN_OOB_FRAMES = 5; 78 static constexpr u8 DEFAULT_OFFSCREEN_TRIGGER_FRAMES = 5; 79 static constexpr u8 DEFAULT_OFFSCREEN_RELEASE_FRAMES = 5; 80 81 s8 m_first_line_offset = 0; 82 s8 m_last_line_offset = 0; 83 s16 m_tick_offset = 0; 84 85 u8 m_offscreen_oob_frames = 0; 86 u8 m_offscreen_trigger_frames = 0; 87 u8 m_offscreen_release_frames = 0; 88 89 u16 m_irq_first_line = 0; 90 u16 m_irq_last_line = 0; 91 u16 m_irq_tick = 0; 92 93 // buttons are active low 94 u16 m_button_state = UINT16_C(0xFFFF); 95 u8 m_shoot_offscreen = 0; 96 bool m_position_valid = false; 97 98 TransferState m_transfer_state = TransferState::Idle; 99 100 TimingEvent m_irq_event; 101 102 bool m_has_relative_binds = false; 103 u8 m_cursor_index = 0; 104 float m_relative_pos[4] = {}; 105 106 std::string m_cursor_path; 107 float m_cursor_scale = 1.0f; 108 u32 m_cursor_color = 0xFFFFFFFFu; 109 float m_x_scale = 1.0f; 110 };