| 1 | #pragma once |
| 2 | |
| 3 | #include "math/seadBoundBox.h" |
| 4 | #include "math/seadVector.h" |
| 5 | #include "prim/seadBitFlag.h" |
| 6 | #include "prim/seadRuntimeTypeInfo.h" |
| 7 | |
| 8 | namespace sead |
| 9 | { |
| 10 | class ControllerBase |
| 11 | { |
| 12 | SEAD_RTTI_BASE(ControllerBase) |
| 13 | public: |
| 14 | static const f32 cStickHoldThresholdDefault; |
| 15 | static const f32 cStickReleaseThresholdDefault; |
| 16 | static const Vector2f cInvalidPointer; |
| 17 | static const Vector2i cInvalidPointerS32; |
| 18 | |
| 19 | ControllerBase(s32 padBitMax, s32 leftStickCrossStartBit, s32 rightStickCrossStartBit, |
| 20 | s32 touchKeyBit); |
| 21 | |
| 22 | u32 getHoldMask() const { return mPadHold.getDirect(); } |
| 23 | u32 getTrigMask() const { return mPadTrig.getDirect(); } |
| 24 | u32 getReleaseMask() const { return mPadRelease.getDirect(); } |
| 25 | u32 getRepeatMask() const { return mPadRepeat.getDirect(); } |
| 26 | |
| 27 | u32 getPadHoldCount(s32 bit) const; |
| 28 | |
| 29 | const Vector2f& getLeftStick() const { return mLeftStick; } |
| 30 | const Vector2f& getRightStick() const { return mRightStick; } |
| 31 | f32 getLeftAnalogTrigger() const { return mLeftAnalogTrigger; } |
| 32 | f32 getRightAnalogTrigger() const { return mRightAnalogTrigger; } |
| 33 | const Vector2f& getPointer() const { return mPointer; } |
| 34 | const Vector2i& getPointerPrev() const { return mPointerS32; } |
| 35 | bool isPointerOn() const { return mPointerFlag.isOn(val: cPointerOn); } |
| 36 | bool isPointerOnNow() const { return mPointerFlag.isOn(val: cPointerOnNow); } |
| 37 | bool isPointerOffNow() const { return mPointerFlag.isOn(val: cPointerOffNow); } |
| 38 | bool isPointerUnkFlag3() const { return mPointerFlag.isOn(val: cPointerUnkFlag3); } |
| 39 | |
| 40 | bool isHold(u32 mask) const { return mask & getHoldMask(); } |
| 41 | bool isTrig(u32 mask) const { return mask & getTrigMask(); } |
| 42 | bool isHoldAll(u32 mask) const { return (mask & getHoldMask()) == mask; } |
| 43 | bool isRelease(u32 mask) const { return mask & getReleaseMask(); } |
| 44 | bool isRepeat(u32 mask) const { return mask & getRepeatMask(); } |
| 45 | |
| 46 | bool isTrigWithRepeat(u32 mask) const |
| 47 | { |
| 48 | u32 trig = getTrigMask(); |
| 49 | u32 repeat = getRepeatMask(); |
| 50 | return (repeat | trig) & mask; |
| 51 | } |
| 52 | |
| 53 | void setPadRepeat(u32 mask, u8 delay_frame, u8 pulse_frame); |
| 54 | |
| 55 | void setLeftStickCrossThreshold(f32 hold, f32 release); |
| 56 | void setRightStickCrossThreshold(f32 hold, f32 release); |
| 57 | |
| 58 | void setPointerBound(const BoundBox2f& bound); |
| 59 | const BoundBox2f& getPointerBound() const { return mPointerBound; } |
| 60 | |
| 61 | protected: |
| 62 | bool isIdleBase_(); |
| 63 | void setIdleBase_(); |
| 64 | void setPointerWithBound_(bool is_on, bool touchkey_hold, const Vector2f& pos); |
| 65 | void updateDerivativeParams_(u32 prev_hold, bool prev_pointer_on); |
| 66 | u32 getStickHold_(u32 prev_hold, const Vector2f& stick, f32 hold_threshold, |
| 67 | f32 release_threshold, s32 start_bit); |
| 68 | u32 createStickCrossMask_(); |
| 69 | |
| 70 | enum |
| 71 | { |
| 72 | cPadIdx_MaxBase = 32 |
| 73 | }; |
| 74 | |
| 75 | enum PointerFlagMask |
| 76 | { |
| 77 | cPointerOn = 1 << 0, |
| 78 | cPointerOnNow = 1 << 1, |
| 79 | cPointerOffNow = 1 << 2, |
| 80 | cPointerUnkFlag3 = 1 << 3 |
| 81 | }; |
| 82 | |
| 83 | enum |
| 84 | { |
| 85 | cCrossUp, |
| 86 | cCrossDown, |
| 87 | cCrossLeft, |
| 88 | cCrossRight |
| 89 | }; |
| 90 | |
| 91 | BitFlag32 mPadTrig; |
| 92 | BitFlag32 mPadRelease; |
| 93 | BitFlag32 mPadRepeat; |
| 94 | BitFlag32 mPointerFlag; |
| 95 | Vector2i mPointerS32; |
| 96 | BoundBox2f mPointerBound; |
| 97 | u32 mPadHoldCounts[cPadIdx_MaxBase]; |
| 98 | u8 mPadRepeatDelays[cPadIdx_MaxBase]; |
| 99 | u8 mPadRepeatPulses[cPadIdx_MaxBase]; |
| 100 | f32 mLeftStickHoldThreshold; |
| 101 | f32 mRightStickHoldThreshold; |
| 102 | f32 mLeftStickReleaseThreshold; |
| 103 | f32 mRightStickReleaseThreshold; |
| 104 | s32 mPadBitMax; |
| 105 | s32 mLeftStickCrossStartBit; |
| 106 | s32 mRightStickCrossStartBit; |
| 107 | s32 mTouchKeyBit; |
| 108 | s32 mIdleFrame; |
| 109 | BitFlag32 mPadHold; |
| 110 | Vector2f mPointer; |
| 111 | Vector2f mLeftStick; |
| 112 | Vector2f mRightStick; |
| 113 | f32 mLeftAnalogTrigger; |
| 114 | f32 mRightAnalogTrigger; |
| 115 | |
| 116 | friend class Controller; |
| 117 | friend class ControllerWrapper; |
| 118 | friend class ControllerWrapperBase; |
| 119 | }; |
| 120 | #ifdef cafe |
| 121 | static_assert(sizeof(ControllerBase) == 0x130, "sead::ControllerBase size mismatch" ); |
| 122 | #endif // cafe |
| 123 | |
| 124 | } // namespace sead |
| 125 | |