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
8namespace sead
9{
10class ControllerBase
11{
12 SEAD_RTTI_BASE(ControllerBase)
13public:
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
61protected:
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
121static_assert(sizeof(ControllerBase) == 0x130, "sead::ControllerBase size mismatch");
122#endif // cafe
123
124} // namespace sead
125