Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
advancedpad.hh
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2025 PCSX-Redux authors
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26
27#pragma once
28
29#include <EASTL/functional.h>
30#include <stdint.h>
31
33
34namespace psyqo {
35
46 public:
47 enum class Pad : unsigned { Pad1a, Pad1b, Pad1c, Pad1d, Pad2a, Pad2b, Pad2c, Pad2d };
48
49 enum Button {
50 Select = 0,
51 L3 = 1,
52 R3 = 2,
53 Start = 3,
54 Up = 4,
55 Right = 5,
56 Down = 6,
57 Left = 7,
58 L2 = 8,
59 R2 = 9,
60 L1 = 10,
61 R1 = 11,
63 Circle = 13,
64 Cross = 14,
65 Square = 15,
66 };
67
68 enum PadType : uint8_t {
69 Mouse = 0x12, // (two button mouse)
70 NegCon = 0x23, // (steering twist/wheel/paddle)
71 KonamiLightgun = 0x31, // (IRQ10-type)
72 DigitalPad = 0x41, // (or analog pad/stick in digital mode; LED=Off)
73 AnalogStick = 0x53, // (or analog pad in "flight mode"; LED=Green)
74 NamcoLightGun = 0x63, // (Cinch-type)
75 AnalogPad = 0x73, // (in normal analog mode; LED=Red)
76 Multitap = 0x80, // (multiplayer adaptor) (when activated)
77 JogCon = 0xe3, // (steering dial)
78 FishingCon = 0xe5, // (fishing rod)
79 ConfigMode = 0xf3, // (when in config mode; see rumble command 43h)
80 None = 0xff // (no controller connected, pins floating High-Z)
81 };
82
88
102 enum class PollingMode { Normal, Fast };
104
114 void setPollingMode(PollingMode mode) { m_portsToProbeByVSync = mode == PollingMode::Normal ? 1 : 2; }
115
134 void setOnEvent(eastl::function<void(Event)>&& callback) { m_callback = eastl::move(callback); }
135
145 bool isPadConnected(Pad pad) const { return m_padData[toUnderlying(pad)].connected == 0; }
146
157 bool isButtonPressed(Pad pad, Button button) const {
158 return (m_padData[toUnderlying(pad)].buttons & (1 << button)) == 0;
159 }
160
175 uint8_t getAdc(Pad pad, unsigned int index) const {
176 const unsigned padIndex = toUnderlying(pad);
177
178 return index <= 7 ? m_padData[padIndex].adc[index] : 0;
179 }
180
198 uint16_t getHalfword(Pad pad, unsigned int index) const { return m_padData[toUnderlying(pad)].packed[index % 4]; }
199
210 uint8_t getPadType(Pad pad) const { return m_padData[toUnderlying(pad)].padType; }
211
218 bool hasAnalog(Pad pad) const {
219 switch (m_padData[toUnderlying(pad)].padType) {
220 case PadType::Mouse:
226 case PadType::None:
227 return false;
228 default:
229 return true;
230 }
231 }
232
233 private:
234 enum Command : uint8_t {
235 PadSelect = 0x01,
236 ReadPad = 0x42, // 'B' Read Buttons AND analog inputs
237 // Config mode commands
238 ToggleConfigMode = 0x43, // 'C' Enter/Exit Configuration Mode
239 SetLED = 0x44, // 'D' Set LED State (analog mode on/off)
240 GetLED = 0x45, // 'E' Get LED State (and whatever values)
241 GetMotorInfo = 0x46, // 'F' Allegedly get info about a motor
242 GetMotorList = 0x47, // 'G' Allegedly get list of motors
243 GetMotorState = 0x48, // 'H' Allegedly get motor state
244 GetSupportedModes = 0x4c, // 'L' Allegedly get supported modes
245 ConfigRequestFormat = 0x4d, // 'M' Allegedly configure poll request format
246 ConfigResponseFormat = 0x4f, // 'O' Allegedly configure poll response format
247 };
248
249 void busyLoop(unsigned delay) {
250#ifndef PS1_PC_PORT
251 unsigned cycles = 0;
252 while (++cycles < delay) asm("");
253#endif
254 };
255
256 void configurePort(uint8_t port);
257
258 void flushRxBuffer();
259 uint8_t outputDefault(unsigned ticks);
260 uint8_t outputMultitap(unsigned ticks);
261 void processChanges(Pad pad);
262 void readPad();
263 uint8_t transceive(uint8_t dataOut);
264 bool waitForAck(); // true if ack received, false if timeout
265
266 union PadData {
267 struct {
268 uint8_t connected;
269 uint8_t padType;
270 uint16_t buttons;
271 uint8_t adc[8];
272 };
273 uint16_t packed[6];
274 };
275
276 PadData m_padData[8];
277 eastl::function<void(Event)> m_callback;
278 bool m_connected[8] = {false, false, false, false, false, false, false, false};
279 uint16_t m_buttons[8] = {
280 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
281 };
282 uint8_t m_portToProbe = 0;
283 uint8_t m_portsToProbeByVSync = 0;
284};
285
286// prefix increment operator
288 return pad = static_cast<psyqo::AdvancedPad::Pad>((toUnderlying(pad) + 1) & 7);
289}
290
291// postfix increment operator
293 psyqo::AdvancedPad::Pad copy(pad);
294 pad = static_cast<psyqo::AdvancedPad::Pad>((toUnderlying(pad) + 1) & 7);
295 return copy;
296}
297
298// prefix decrement operator
300 return pad = static_cast<psyqo::AdvancedPad::Pad>((toUnderlying(pad) - 1) & 7);
301}
302
303// postfix decrement operator
305 psyqo::AdvancedPad::Pad copy(pad);
306 pad = static_cast<psyqo::AdvancedPad::Pad>((toUnderlying(pad) - 1) & 7);
307 return copy;
308}
309
310} // namespace psyqo
An advanced class to access the pads.
Definition advancedpad.hh:45
PadType
Definition advancedpad.hh:68
@ JogCon
Definition advancedpad.hh:77
@ None
Definition advancedpad.hh:80
@ Mouse
Definition advancedpad.hh:69
@ NamcoLightGun
Definition advancedpad.hh:74
@ DigitalPad
Definition advancedpad.hh:72
@ NegCon
Definition advancedpad.hh:70
@ AnalogStick
Definition advancedpad.hh:73
@ Multitap
Definition advancedpad.hh:76
@ KonamiLightgun
Definition advancedpad.hh:71
@ ConfigMode
Definition advancedpad.hh:79
@ AnalogPad
Definition advancedpad.hh:75
@ FishingCon
Definition advancedpad.hh:78
PollingMode
Initializes the pads.
Definition advancedpad.hh:102
Pad
Definition advancedpad.hh:47
void setPollingMode(PollingMode mode)
Changes the polling mode after initialize.
Definition advancedpad.hh:114
uint8_t getAdc(Pad pad, unsigned int index) const
Returns the state of an Analog Input.
Definition advancedpad.hh:175
Button
Definition advancedpad.hh:49
@ Up
Definition advancedpad.hh:54
@ Select
Definition advancedpad.hh:50
@ L3
Definition advancedpad.hh:51
@ L1
Definition advancedpad.hh:60
@ Circle
Definition advancedpad.hh:63
@ R2
Definition advancedpad.hh:59
@ Triangle
Definition advancedpad.hh:62
@ Cross
Definition advancedpad.hh:64
@ Square
Definition advancedpad.hh:65
@ Right
Definition advancedpad.hh:55
@ Left
Definition advancedpad.hh:57
@ Start
Definition advancedpad.hh:53
@ R1
Definition advancedpad.hh:61
@ Down
Definition advancedpad.hh:56
@ L2
Definition advancedpad.hh:58
@ R3
Definition advancedpad.hh:52
bool isPadConnected(Pad pad) const
Returns the state of a pad.
Definition advancedpad.hh:145
bool isButtonPressed(Pad pad, Button button) const
Returns the state of a button.
Definition advancedpad.hh:157
bool hasAnalog(Pad pad) const
Checks if the specified pad can do analog.
Definition advancedpad.hh:218
uint8_t getPadType(Pad pad) const
Returns the type of the pad.
Definition advancedpad.hh:210
void setOnEvent(eastl::function< void(Event)> &&callback)
Sets the event callback function.
Definition advancedpad.hh:134
uint16_t getHalfword(Pad pad, unsigned int index) const
Returns raw pad data as an unsigned 16-bit value.
Definition advancedpad.hh:198
void initialize(PollingMode mode=PollingMode::Normal)
Definition advancedpad.cpp:38
Definition lua.hh:40
psyqo::AdvancedPad::Pad & operator++(psyqo::AdvancedPad::Pad &pad)
Definition advancedpad.hh:287
psyqo::AdvancedPad::Pad & operator--(psyqo::AdvancedPad::Pad &pad)
Definition advancedpad.hh:299
constexpr std::underlying_type_t< E > toUnderlying(E v)
Definition utility-polyfill.h:38
Definition advancedpad.hh:83
Button button
Definition advancedpad.hh:86
Pad pad
Definition advancedpad.hh:85
enum psyqo::AdvancedPad::Event::@30 type
@ PadConnected
Definition advancedpad.hh:84
@ PadDisconnected
Definition advancedpad.hh:84
@ ButtonPressed
Definition advancedpad.hh:84
@ ButtonReleased
Definition advancedpad.hh:84
static void uint32_t mode
Definition syscalls.h:274