PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
libpad.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
18#include <tamtypes.h>
19#include <kernel.h>
20#include <stdio.h>
21#include <string.h>
22#include <sifrpc.h>
23#include <sifcmd.h>
24#include "libpad.h"
25
26/*
27 * Defines
28 */
29
30#ifdef _XPAD
31#define PAD_BIND_RPC_ID1 0x80000100
32#define PAD_BIND_RPC_ID2 0x80000101
33
34#define PAD_RPCCMD_OPEN 0x01
35#define PAD_RPCCMD_SET_MMODE 0x06
36#define PAD_RPCCMD_SET_ACTDIR 0x07
37#define PAD_RPCCMD_SET_ACTALIGN 0x08
38#define PAD_RPCCMD_GET_BTNMASK 0x09
39#define PAD_RPCCMD_SET_BTNINFO 0x0A
40#define PAD_RPCCMD_SET_VREF 0x0B
41#define PAD_RPCCMD_GET_PORTMAX 0x0C
42#define PAD_RPCCMD_GET_SLOTMAX 0x0D
43#define PAD_RPCCMD_CLOSE 0x0E
44#define PAD_RPCCMD_END 0x0F
45#define PAD_RPCCMD_INIT 0x10
46#define PAD_RPCCMD_GET_MODVER 0x12
47#else
48#define PAD_BIND_RPC_ID1 0x8000010f
49#define PAD_BIND_RPC_ID2 0x8000011f
50
51#define PAD_RPCCMD_OPEN 0x80000100
52#define PAD_RPCCMD_INFO_ACT 0x80000102
53#define PAD_RPCCMD_INFO_COMB 0x80000103
54#define PAD_RPCCMD_INFO_MODE 0x80000104
55#define PAD_RPCCMD_SET_MMODE 0x80000105
56#define PAD_RPCCMD_SET_ACTDIR 0x80000106
57#define PAD_RPCCMD_SET_ACTALIGN 0x80000107
58#define PAD_RPCCMD_GET_BTNMASK 0x80000108
59#define PAD_RPCCMD_SET_BTNINFO 0x80000109
60#define PAD_RPCCMD_SET_VREF 0x8000010a
61#define PAD_RPCCMD_GET_PORTMAX 0x8000010b
62#define PAD_RPCCMD_GET_SLOTMAX 0x8000010c
63#define PAD_RPCCMD_CLOSE 0x8000010d
64#define PAD_RPCCMD_END 0x8000010e
65#define PAD_RPCCMD_INIT 0x00000100
66#endif
67
68/*
69 * Types
70 */
71
73{
74 int open;
75 unsigned int port;
76 unsigned int slot;
77 struct pad_data *padData;
78 unsigned char *padBuf;
79};
80
81#ifdef _XPAD
82struct pad_data
83{
84 u8 data[32];
85 u32 actDirData[2];
86 u32 actAlignData[2];
87 u8 actData[32];
88 u16 modeTable[4];
89 u32 frame;
90 u32 findPadRetries;
91 u32 length;
92 u8 modeConfig;
93 u8 modeCurId;
94 u8 model;
95 u8 buttonDataReady;
96 u8 nrOfModes;
97 u8 modeCurOffs;
98 u8 nrOfActuators;
99 u8 numActComb;
100 u8 val_c6;
101 u8 mode;
102 u8 lock;
103 u8 actDirSize;
104 u8 state;
105 u8 reqState;
106 u8 currentTask;
107 u8 runTask;
108 u8 stat70bit;
109 u8 padding[11];
110};
111
112struct open_slot
113{
114 u32 frame;
115 u32 openSlots[2];
116 u8 padding[116];
117};
118#else
119// rom0:padman has only 64 byte of pad data
121{
122 unsigned int frame;
123 unsigned char state;
124 unsigned char reqState;
125 unsigned char ok;
126 unsigned char unkn7;
127 unsigned char data[32];
128 unsigned int length;
129 unsigned char request;
131 unsigned char CTP;
133 unsigned char model;
135 unsigned char correction;
136 unsigned char errorCount;
137 unsigned char unk49[15];
138};
139#endif
140
141extern int _iop_reboot_count;
142/*
143 * Pad variables etc.
144 */
145
146static const char padStateString[8][16] = {"DISCONNECT", "FINDPAD",
147 "FINDCTP1", "", "", "EXECCMD",
148 "STABLE", "ERROR"};
149static const char padReqStateString[3][16] = {"COMPLETE", "FAILED", "BUSY"};
150
151static int padInitialised = 0;
152
153// pad rpc call
154static SifRpcClientData_t padsif[2] __attribute__((aligned(64)));
155static union {
156 s32 command;
157#ifdef _XPAD
158 struct {
159 s32 command;
160 s32 unused[3];
161 void *statBuf;
162 } padInitArgs;
163#endif
164 struct {
165 s32 unknown[3];
166 s32 result;
167 s32 unknown2;
168 void *padBuf;
169 } padOpenResult;
170 struct {
171 s32 unknown[3];
172 s32 result;
173 } padResult;
174 struct {
175 s32 command;
176 s32 port, slot;
177 s32 unknown;
178 void *padArea;
179 } padOpenArgs;
180 struct {
181 s32 command;
182 s32 port, slot;
183 s32 unknown;
184 s32 mode;
185 } padCloseArgs;
186 struct {
187 s32 command;
188 s32 port;
189 } padSlotMaxArgs;
190 struct {
191 s32 command;
192 s32 port, slot;
193 s32 infoMode;
194 s32 index;
195 } padInfoModeArgs;
196 struct {
197 s32 command;
198 s32 port, slot;
199 s32 mode;
200 s32 lock;
201 } padSetMainModeArgs;
202 struct {
203 s32 unknown[5];
204 s32 result;
205 } padModeResult;
206 struct {
207 s32 command;
208 s32 port, slot;
209 } padGetButtonMaskArgs;
210 struct {
211 s32 command;
212 s32 port, slot;
213 s32 buttonInfo;
214 } padSetButtonInfoArgs;
215 struct {
216 s32 unknown[4];
217 s32 result;
218 } padSetButtonInfoResult;
219 struct {
220 s32 command;
221 s32 port, slot;
222#ifndef _XPAD
223 s32 actuator;
224 s32 act_cmd;
225 } padInfoActArgs;
226 struct {
227 s32 command;
228 s32 port, slot;
229#endif
230 s8 align[6];
231 } padActDirAlignArgs;
232 char buffer[128];
233}
234#ifdef _XPAD
235buffer __attribute__((aligned(64)));
236#else
237buffer __attribute__((aligned(16)));
238#endif
239
241#ifdef _XPAD
242static struct open_slot openSlot[2] __attribute__((aligned(64)));
243#endif
244static struct pad_state PadState[2][8];
245
246
247/*
248 * Local functions
249 */
250
252static struct pad_data*
253padGetDmaStr(int port, int slot)
254{
255 struct pad_data *pdata;
256
257 pdata = PadState[port][slot].padData;
258 SyncDCache(pdata, (u8 *)pdata + 256);
259
260 if(pdata[0].frame < pdata[1].frame) {
261 return &pdata[1];
262 }
263 else {
264 return &pdata[0];
265 }
266}
267
268#ifdef _XPAD
273static struct open_slot*
274padGetConnDmaStr(void)
275{
276 SyncDCache(openSlot, (u8*)openSlot + sizeof(openSlot));
277
278 if(openSlot[0].frame < openSlot[1].frame)
279 return &openSlot[1];
280 else
281 return &openSlot[0];
282}
283#endif
284
285/*
286 * Global functions
287 */
288
289/*
290 * Functions not implemented here
291 * padGetFrameCount() <- dunno if it's useful for someone..
292 * padInfoComb() <- see above
293 * padSetVrefParam() <- dunno
294 */
295
296int
297padInit(int mode)
298{
299 // Version check isn't used by default
300 // int ver;
301 static int _rb_count = 0;
302
303 if (_rb_count != _iop_reboot_count)
304 {
305 _rb_count = _iop_reboot_count;
306 padInitialised = 0;
307 }
308
309 if(padInitialised)
310 return 0;
311
312 padInitialised = 1;
313
314 padsif[0].server = NULL;
315 padsif[1].server = NULL;
316
317 do {
318 if (SifBindRpc(&padsif[0], PAD_BIND_RPC_ID1, 0) < 0) {
319 return -1;
320 }
321 nopdelay();
322 } while(!padsif[0].server);
323
324 do {
325 if (SifBindRpc(&padsif[1], PAD_BIND_RPC_ID2, 0) < 0) {
326 return -3;
327 }
328 nopdelay();
329 } while(!padsif[1].server);
330
331 // If you require a special version of the padman, check for that here (uncomment)
332 // ver = padGetModVersion();
333
334 //At v1.3.4, this used to return 1 (and padPortInit is not used). But we are interested in the better design from release 1.4.
335 return padPortInit(mode);
336}
337
338int padPortInit(int mode)
339{
340#ifdef _XPAD //Unofficial: libpad EE client from v1.3.4 has this RPC function implemented, but is not implemented within its PADMAN module.
341 int ret;
342#endif
343 int i;
344
345 (void)mode;
346
347 for(i = 0; i<8; i++)
348 {
349 PadState[0][i].open = 0;
350 PadState[0][i].port = 0;
351 PadState[0][i].slot = 0;
352 PadState[1][i].open = 0;
353 PadState[1][i].port = 0;
354 PadState[1][i].slot = 0;
355 }
356
357#ifdef _XPAD //Unofficial: libpad EE client from v1.3.4 has this RPC function implemented, but is not implemented within its PADMAN module.
358
359#ifdef _XPAD
360 buffer.padInitArgs.command = PAD_RPCCMD_INIT;
361 buffer.padInitArgs.statBuf = openSlot;
362#else
363 buffer.command = PAD_RPCCMD_INIT;
364#endif
365 ret = SifCallRpc( &padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL);
366
367 return(ret >= 0 ? buffer.padResult.result : 0);
368#else
369 return 1;
370#endif
371}
372
373int
375{
376
377 int ret;
378
379
380 buffer.command=PAD_RPCCMD_END;
381
382 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
383 return -1;
384
385 ret = buffer.padResult.result;
386 if (ret == 1) {
387 padInitialised = 0;
388 }
389
390 return ret;
391}
392
393int
394padPortOpen(int port, int slot, void *padArea)
395{
396
397 int i;
398 struct pad_data *dma_buf = (struct pad_data *)padArea;
399
400#ifndef _XPAD
401 // Check 16 byte alignment
402 if((u32)padArea & 0xf) {
403 printf("Address is not 16-byte aligned.\n");
404 return 0;
405 }
406#else
407 // Check 64 byte alignment
408 if((u32)padArea & 0x3f) {
409 printf("Address is not 16-byte aligned.\n");
410 return 0;
411 }
412#endif
413
414 for (i=0; i<2; i++) { // Pad data is double buffered
415 memset(dma_buf[i].data, 0xff, 32); // 'Clear' data area
416 dma_buf[i].frame = 0;
417 dma_buf[i].length = 0;
418 dma_buf[i].state = PAD_STATE_EXECCMD;
419 dma_buf[i].reqState = PAD_RSTAT_BUSY;
420#ifndef _XPAD
421 dma_buf[i].ok = 0;
422#endif
423#ifdef _XPAD
424 dma_buf[i].currentTask = 0;
425#endif
426 dma_buf[i].length = 0;
427#ifdef _XPAD
428 dma_buf[i].buttonDataReady = 0; // Should be cleared in newer padman
429#endif
430 }
431
432
433 buffer.padOpenArgs.command = PAD_RPCCMD_OPEN;
434 buffer.padOpenArgs.port = port;
435 buffer.padOpenArgs.slot = slot;
436 buffer.padOpenArgs.padArea = padArea;
437
438 if(SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
439 {
440 return 0;
441 }
442
443 PadState[port][slot].open = 1;
444 PadState[port][slot].padData = padArea;
445 PadState[port][slot].padBuf = buffer.padOpenResult.padBuf;
446
447 return buffer.padOpenResult.result;
448}
449
450int
451padPortClose(int port, int slot)
452{
453
454 int ret;
455
456 buffer.padCloseArgs.command = PAD_RPCCMD_CLOSE;
457 buffer.padCloseArgs.port = port;
458 buffer.padCloseArgs.slot = slot;
459 buffer.padCloseArgs.mode = 1;
460
461 ret = SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL);
462
463 if(ret < 0)
464 return ret;
465 else {
466 PadState[port][slot].open = 0;
467 return buffer.padResult.result;
468 }
469}
470
471unsigned char
472padRead(int port, int slot, struct padButtonStatus *data)
473{
474
475 struct pad_data *pdata;
476
477 pdata = padGetDmaStr(port, slot);
478
479 memcpy(data, pdata->data, pdata->length);
480 return pdata->length;
481}
482
483int
484padGetState(int port, int slot)
485{
486 struct pad_data *pdata;
487 unsigned char state;
488
489
490 pdata = padGetDmaStr(port, slot);
491
492 state = pdata->state;
493
494#ifdef _XPAD
495 if (state == PAD_STATE_ERROR)
496 {
497 if (pdata->findPadRetries)
498 {
499 return PAD_STATE_FINDPAD;
500 }
501 }
502#endif
503
504 if (state == PAD_STATE_STABLE) { // Ok
505 if (padGetReqState(port, slot) == PAD_RSTAT_BUSY) {
506 return PAD_STATE_EXECCMD;
507 }
508 }
509 return state;
510}
511
512unsigned char
513padGetReqState(int port, int slot)
514{
515
516 struct pad_data *pdata;
517
518 pdata = padGetDmaStr(port, slot);
519 return pdata->reqState;
520}
521
522int
523padSetReqState(int port, int slot, int state)
524{
525
526 struct pad_data *pdata;
527
528 pdata = padGetDmaStr(port, slot);
529 pdata->reqState = state;
530 return 1;
531}
532
533void
534padStateInt2String(int state, char buf[16])
535{
536
537 if(state < 8) {
538 strcpy(buf, padStateString[state]);
539 }
540}
541
542void
543padReqStateInt2String(int state, char buf[16])
544{
545 if(state < 3)
546 strcpy(buf, padReqStateString[state]);
547}
548
549int
551{
552
553 buffer.command = PAD_RPCCMD_GET_PORTMAX;
554
555 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
556 return -1;
557
558 return buffer.padResult.result;
559}
560
561int
563{
564
565 buffer.padSlotMaxArgs.command = PAD_RPCCMD_GET_SLOTMAX;
566 buffer.padSlotMaxArgs.port = port;
567
568 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
569 return -1;
570
571 return buffer.padResult.result;
572}
573
574int
576{
577#ifdef _XPAD
578 buffer.command = PAD_RPCCMD_GET_MODVER;
579
580 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
581 return -1;
582
583 return buffer.padResult.result;
584#else
585 return 1; // Well.. return a low version #
586#endif
587}
588
589int
590padInfoMode(int port, int slot, int infoMode, int index)
591{
592#ifdef _XPAD
593 struct pad_data *pdata;
594
595 pdata = padGetDmaStr(port, slot);
596
597 if (pdata->currentTask != 1)
598 return 0;
599 if (pdata->reqState == PAD_RSTAT_BUSY)
600 return 0;
601
602 switch(infoMode) {
603 case PAD_MODECURID:
604 if (pdata->modeCurId == 0xF3)
605 return 0;
606 else
607 return (pdata->modeCurId >> 4);
608 break;
609
610 case PAD_MODECUREXID:
611 if (pdata->modeConfig == pdata->currentTask)
612 return 0;
613 return pdata->modeTable[pdata->modeCurOffs];
614 break;
615
616 case PAD_MODECUROFFS:
617 if (pdata->modeConfig != 0)
618 return pdata->modeCurOffs;
619 else
620 return 0;
621 break;
622
623 case PAD_MODETABLE:
624 if (pdata->modeConfig != 0) {
625 if(index == -1) {
626 return pdata->nrOfModes;
627 }
628 else if (index < pdata->nrOfModes) {
629 return pdata->modeTable[index];
630 }
631 else {
632 return 0;
633 }
634 }
635 else
636 return 0;
637 break;
638 }
639 return 0;
640#else
641 buffer.padInfoModeArgs.command = PAD_RPCCMD_INFO_MODE;
642 buffer.padInfoModeArgs.port = port;
643 buffer.padInfoModeArgs.slot = slot;
644 buffer.padInfoModeArgs.infoMode = infoMode;
645 buffer.padInfoModeArgs.index = index;
646
647 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
648 return 0;
649
650 if (buffer.padModeResult.result == 1) {
651 padSetReqState(port, slot, PAD_RSTAT_BUSY);
652 }
653 return buffer.padModeResult.result;
654#endif
655}
656
657int
658padSetMainMode(int port, int slot, int mode, int lock)
659{
660
661 buffer.padSetMainModeArgs.command = PAD_RPCCMD_SET_MMODE;
662 buffer.padSetMainModeArgs.port = port;
663 buffer.padSetMainModeArgs.slot = slot;
664 buffer.padSetMainModeArgs.mode = mode;
665 buffer.padSetMainModeArgs.lock = lock;
666
667 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
668 return 0;
669
670 if (buffer.padModeResult.result == 1) {
671 padSetReqState(port, slot, PAD_RSTAT_BUSY);
672 }
673 return buffer.padModeResult.result;
674}
675
676int
677padInfoPressMode(int port, int slot)
678{
679 int mask;
680
681 mask = padGetButtonMask(port, slot);
682
683 if (mask^0x3ffff) {
684 return 0;
685 }
686 else {
687 return 1;
688 }
689}
690
691int
692padEnterPressMode(int port, int slot)
693{
694 return padSetButtonInfo(port, slot, 0xFFF);
695}
696
697int
698padExitPressMode(int port, int slot)
699{
700 return padSetButtonInfo(port, slot, 0);
701
702}
703
704int
705padGetButtonMask(int port, int slot)
706{
707
708 buffer.padGetButtonMaskArgs.command = PAD_RPCCMD_GET_BTNMASK;
709 buffer.padGetButtonMaskArgs.port = port;
710 buffer.padGetButtonMaskArgs.slot = slot;
711
712 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
713 return 0;
714
715 return buffer.padResult.result;
716}
717
718int
719padSetButtonInfo(int port, int slot, int buttonInfo)
720{
721 int val;
722
723 buffer.padSetButtonInfoArgs.command = PAD_RPCCMD_SET_BTNINFO;
724 buffer.padSetButtonInfoArgs.port = port;
725 buffer.padSetButtonInfoArgs.slot = slot;
726 buffer.padSetButtonInfoArgs.buttonInfo = buttonInfo;
727
728 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
729 return 0;
730
731 val = buffer.padSetButtonInfoResult.result;
732
733 if (val == 1) {
734 padSetReqState(port, slot, PAD_RSTAT_BUSY);
735 }
736 return buffer.padSetButtonInfoResult.result;
737}
738
739unsigned char
740padInfoAct(int port, int slot, int actuator, int cmd)
741{
742#ifdef _XPAD
743 struct pad_data *pdata;
744
745 pdata = padGetDmaStr(port, slot);
746
747 if (pdata->currentTask != 1)
748 return 0;
749 if (pdata->modeConfig < 2)
750 return 0;
751 if (actuator >= pdata->nrOfActuators)
752 return 0;
753
754 if (actuator == -1)
755 return pdata->nrOfActuators; // # of acutators?
756
757 if (cmd >= 4)
758 return 0;
759
760 return pdata->actData[actuator*4+cmd];
761#else
762 buffer.padInfoActArgs.command = PAD_RPCCMD_INFO_ACT;
763 buffer.padInfoActArgs.port = port;
764 buffer.padInfoActArgs.slot = slot;
765 buffer.padInfoActArgs.actuator = actuator;
766 buffer.padInfoActArgs.act_cmd = cmd;
767
768 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
769 return 0;
770
771 if (buffer.padModeResult.result == 1) {
772 padSetReqState(port, slot, PAD_RSTAT_BUSY);
773 }
774 return buffer.padModeResult.result;
775#endif
776}
777
778int
779padSetActAlign(int port, int slot, const char actAlign[6])
780{
781 int i;
782 s8 *ptr;
783
784 buffer.padActDirAlignArgs.command = PAD_RPCCMD_SET_ACTALIGN;
785 buffer.padActDirAlignArgs.port = port;
786 buffer.padActDirAlignArgs.slot = slot;
787
788 ptr = buffer.padActDirAlignArgs.align;
789 for (i=0; i<6; i++)
790 ptr[i]=actAlign[i];
791
792 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
793 return 0;
794
795 if (buffer.padModeResult.result == 1) {
796 padSetReqState(port, slot, PAD_RSTAT_BUSY);
797 }
798 return buffer.padModeResult.result;
799}
800
801int
802padSetActDirect(int port, int slot, char actAlign[6])
803{
804 int i;
805 s8 *ptr;
806
807 buffer.padActDirAlignArgs.command = PAD_RPCCMD_SET_ACTDIR;
808 buffer.padActDirAlignArgs.port = port;
809 buffer.padActDirAlignArgs.slot = slot;
810
811 ptr = buffer.padActDirAlignArgs.align;
812 for (i=0; i<6; i++)
813 ptr[i]=actAlign[i];
814
815 if (SifCallRpc(&padsif[0], 1, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
816 return 0;
817
818 return buffer.padModeResult.result;
819}
820
821/*
822 * This seems to have been removed from the official SDKs, very early during the PS2's lifetime.
823 */
824int
825padGetConnection(int port, int slot)
826{
827#ifdef _XPAD
828 struct open_slot *oslot;
829
830 oslot = padGetConnDmaStr();
831
832 return ((oslot->openSlots[port] >> slot) & 0x1);
833#else
834 (void)port;
835 (void)slot;
836 return 1;
837#endif
838}
int padGetPortMax(void)
Definition libpad.c:550
int padPortOpen(int port, int slot, void *padArea)
Definition libpad.c:394
int padPortInit(int mode)
Definition libpad.c:338
unsigned char correction
Definition libpad.c:135
unsigned char padRead(int port, int slot, struct padButtonStatus *data)
Definition libpad.c:472
int padInfoMode(int port, int slot, int infoMode, int index)
Definition libpad.c:590
unsigned char padInfoAct(int port, int slot, int actuator, int cmd)
Definition libpad.c:740
int padExitPressMode(int port, int slot)
Definition libpad.c:698
int padGetModVersion()
Definition libpad.c:575
static struct pad_data * padGetDmaStr(int port, int slot)
Definition libpad.c:253
unsigned char CTP
Definition libpad.c:131
int padInit(int mode)
Definition libpad.c:297
int padGetConnection(int port, int slot)
Definition libpad.c:825
int padSetActDirect(int port, int slot, char actAlign[6])
Definition libpad.c:802
int padSetReqState(int port, int slot, int state)
Definition libpad.c:523
int padPortClose(int port, int slot)
Definition libpad.c:451
int padEnd(void)
Definition libpad.c:374
int padGetState(int port, int slot)
Definition libpad.c:484
unsigned char padGetReqState(int port, int slot)
Definition libpad.c:513
static struct pad_state PadState[2][8]
Definition libpad.c:244
unsigned char model
Definition libpad.c:133
int padInfoPressMode(int port, int slot)
Definition libpad.c:677
int padSetMainMode(int port, int slot, int mode, int lock)
Definition libpad.c:658
int padEnterPressMode(int port, int slot)
Definition libpad.c:692
int padGetSlotMax(int port)
Definition libpad.c:562
int padSetActAlign(int port, int slot, const char actAlign[6])
Definition libpad.c:779