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#define PAD_BIND_RPC_ID1_NEW 0x80000100
31#define PAD_BIND_RPC_ID2_NEW 0x80000101
32
33#define PAD_BIND_RPC_ID1_OLD 0x8000010f
34#define PAD_BIND_RPC_ID2_OLD 0x8000011f
35
36#define PAD_RPCCMD_OPEN_NEW 0x01
37#define PAD_RPCCMD_SET_MMODE_NEW 0x06
38#define PAD_RPCCMD_SET_ACTDIR_NEW 0x07
39#define PAD_RPCCMD_SET_ACTALIGN_NEW 0x08
40#define PAD_RPCCMD_GET_BTNMASK_NEW 0x09
41#define PAD_RPCCMD_SET_BTNINFO_NEW 0x0A
42#define PAD_RPCCMD_SET_VREF_NEW 0x0B
43#define PAD_RPCCMD_GET_PORTMAX_NEW 0x0C
44#define PAD_RPCCMD_GET_SLOTMAX_NEW 0x0D
45#define PAD_RPCCMD_CLOSE_NEW 0x0E
46#define PAD_RPCCMD_END_NEW 0x0F
47#define PAD_RPCCMD_INIT 0x10
48#define PAD_RPCCMD_GET_MODVER 0x12
49
50#define PAD_RPCCMD_OPEN_OLD 0x80000100
51#define PAD_RPCCMD_INFO_ACT 0x80000102
52#define PAD_RPCCMD_INFO_COMB_OLD 0x80000103
53#define PAD_RPCCMD_INFO_MODE 0x80000104
54#define PAD_RPCCMD_SET_MMODE_OLD 0x80000105
55#define PAD_RPCCMD_SET_ACTDIR_OLD 0x80000106
56#define PAD_RPCCMD_SET_ACTALIGN_OLD 0x80000107
57#define PAD_RPCCMD_GET_BTNMASK_OLD 0x80000108
58#define PAD_RPCCMD_SET_BTNINFO_OLD 0x80000109
59#define PAD_RPCCMD_SET_VREF_OLD 0x8000010a
60#define PAD_RPCCMD_GET_PORTMAX_OLD 0x8000010b
61#define PAD_RPCCMD_GET_SLOTMAX_OLD 0x8000010c
62#define PAD_RPCCMD_CLOSE_OLD 0x8000010d
63#define PAD_RPCCMD_END_OLD 0x8000010e
64
65/*
66 * Types
67 */
68
70{
71 u8 data[32];
72 u32 actDirData[2];
73 u32 actAlignData[2];
74 u8 actData[8][4];
75 u16 modeTable[4];
76 u32 frame;
77 u32 findPadRetries;
78 u32 length;
79 u8 modeConfig;
80 u8 modeCurId;
81 u8 model;
82 u8 buttonDataReady;
83 u8 nrOfModes;
84 u8 modeCurOffs;
85 u8 nrOfActuators;
86 u8 numActComb;
87 u8 val_c6;
88 u8 mode;
89 u8 lock;
90 u8 actDirSize;
91 u8 state;
92 u8 reqState;
93 u8 currentTask;
94 u8 runTask;
95 u8 stat70bit;
96 u8 padding[11];
97};
98
99// rom0:padman has only 64 byte of pad data
101{
102 u32 frame;
103 u8 state;
104 u8 reqState;
105 u8 ok;
106 u8 unkn7;
107 u8 data[32];
108 u32 length;
109 u8 request;
111 u8 CTP;
116 u8 errorCount;
117 u8 unk49[15];
118};
119
121{
122 struct pad_data_old oldPadData[2];
123 struct pad_data_new newPadData[2];
124};
125
127{
128 int open;
129 unsigned int port;
130 unsigned int slot;
131 union pad_data_u *padData;
132 unsigned char *padBuf;
133};
134
136{
137 u32 frame;
138 u32 openSlots[2];
139 u8 padding[116];
140};
141
142extern int _iop_reboot_count;
143/*
144 * Pad variables etc.
145 */
146
147static const char *padStateString[] = {
148 "DISCONNECT",
149 "FINDPAD",
150 "FINDCTP1",
151 "",
152 "",
153 "EXECCMD",
154 "STABLE",
155 "ERROR",
156};
157static const char *padReqStateString[] = {
158 "COMPLETE",
159 "FAILED",
160 "BUSY",
161};
162
163static int padInitialised = 0;
164
165// pad rpc call
167static union {
168 s32 command;
169 struct {
170 s32 command;
171 s32 unused[3];
172 void *statBuf;
173 } padInitArgs;
174 struct {
175 s32 unknown[3];
176 s32 result;
177 s32 unknown2;
178 void *padBuf;
179 } padOpenResult;
180 struct {
181 s32 unknown[3];
182 s32 result;
183 } padResult;
184 struct {
185 s32 command;
186 s32 port, slot;
187 s32 unknown;
188 void *padArea;
189 } padOpenArgs;
190 struct {
191 s32 command;
192 s32 port, slot;
193 s32 unknown;
194 s32 mode;
195 } padCloseArgs;
196 struct {
197 s32 command;
198 s32 port;
199 } padSlotMaxArgs;
200 struct {
201 s32 command;
202 s32 port, slot;
203 s32 infoMode;
204 s32 index;
205 } padInfoModeArgs;
206 struct {
207 s32 command;
208 s32 port, slot;
209 s32 mode;
210 s32 lock;
211 } padSetMainModeArgs;
212 struct {
213 s32 unknown[5];
214 s32 result;
215 } padModeResult;
216 struct {
217 s32 command;
218 s32 port, slot;
219 } padGetButtonMaskArgs;
220 struct {
221 s32 command;
222 s32 port, slot;
223 s32 buttonInfo;
224 } padSetButtonInfoArgs;
225 struct {
226 s32 unknown[4];
227 s32 result;
228 } padSetButtonInfoResult;
229 struct {
230 s32 command;
231 s32 port, slot;
232 s32 actuator;
233 s32 act_cmd;
234 } padInfoActArgs;
235 struct {
236 s32 command;
237 s32 port, slot;
238 s8 align[6];
239 } padActDirAlignArgs;
240 char buffer[128];
241}
242buffer __attribute__((aligned(64)));
243
245static struct open_slot openSlot[2] __attribute__((aligned(64)));
246static struct pad_state PadState[2][8];
247
248
249/*
250 * Local functions
251 */
252
254static struct pad_data_new*
255padGetDmaStrNew(int port, int slot)
256{
257 struct pad_data_new *pdata;
258
259 pdata = PadState[port][slot].padData->newPadData;
260 SyncDCache(pdata, (u8 *)pdata + 256);
261
262 return (pdata[0].frame < pdata[1].frame) ? &pdata[1] : &pdata[0];
263}
264
265static struct pad_data_old*
266padGetDmaStrOld(int port, int slot)
267{
268 struct pad_data_old *pdata;
269
270 pdata = PadState[port][slot].padData->oldPadData;
271 SyncDCache(pdata, (u8 *)pdata + 256);
272
273 return (pdata[0].frame < pdata[1].frame) ? &pdata[1] : &pdata[0];
274}
275
280static struct open_slot*
282{
283 SyncDCache(openSlot, (u8*)openSlot + sizeof(openSlot));
284
285 return (openSlot[0].frame < openSlot[1].frame) ? &openSlot[1] : &openSlot[0];
286}
287
288/*
289 * Global functions
290 */
291
292/*
293 * Functions not implemented here
294 * padGetFrameCount() <- dunno if it's useful for someone..
295 * padInfoComb() <- see above
296 * padSetVrefParam() <- dunno
297 */
298
299int
300padInit(int mode)
301{
302 // Version check isn't used by default
303 // int ver;
304 static int _rb_count = 0;
305 int rpc_init_next;
306
307 if (_rb_count != _iop_reboot_count)
308 {
309 _rb_count = _iop_reboot_count;
310 padInitialised = 0;
311 }
312
313 if (padInitialised)
314 return 0;
315
316 padInitialised = 0xFFFFFFFF;
317 rpc_init_next = 0;
318
319 padsif[0].server = NULL;
320 padsif[1].server = NULL;
321
322 {
323 unsigned int i;
324 SifRpcClientData_t rpciftmp[2] __attribute__((aligned(64)));
325 static const int rpc_ids[] = {
326 PAD_BIND_RPC_ID1_NEW,
327 PAD_BIND_RPC_ID1_OLD,
328 };
329
330 padsif[0].server = NULL;
331 for (i = 0; i < (sizeof(rpc_ids)/sizeof(rpc_ids[0])); i += 1)
332 rpciftmp[i].server = NULL;
333
334 for (;;)
335 {
336 for (i = 0; i < (sizeof(rpc_ids)/sizeof(rpc_ids[0])); i += 1)
337 {
338 if ((sceSifBindRpc(&rpciftmp[i], rpc_ids[i], 0) < 0))
339 return -1;
340 if (rpciftmp[i].server != NULL)
341 {
342 switch (rpc_ids[i])
343 {
344 case PAD_BIND_RPC_ID1_NEW:
345 {
346 padInitialised = 2;
347 rpc_init_next = PAD_BIND_RPC_ID2_NEW;
348 break;
349 }
350 case PAD_BIND_RPC_ID1_OLD:
351 {
352 padInitialised = 1;
353 rpc_init_next = PAD_BIND_RPC_ID2_OLD;
354 break;
355 }
356 default:
357 break;
358 }
359 memcpy(&padsif[0], &rpciftmp[i], sizeof(padsif[0]));
360 break;
361 }
362 }
363 if (padsif[0].server != NULL)
364 break;
365 nopdelay();
366 }
367 }
368
369 if (!rpc_init_next)
370 return -1;
371
372 while (!padsif[1].server)
373 {
374 if (sceSifBindRpc(&padsif[1], rpc_init_next, 0) < 0)
375 return -3;
376 nopdelay();
377 }
378
379 // If you require a special version of the padman, check for that here (uncomment)
380 // ver = padGetModVersion();
381
382 //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.
383 return padPortInit(mode);
384}
385
386int padPortInit(int mode)
387{
388 unsigned int i;
389 unsigned int j;
390
391 (void)mode;
392
393 for (i = 0; i < (sizeof(PadState)/sizeof(PadState[0])); i += 1)
394 {
395 for (j = 0; j < (sizeof(PadState[0])/sizeof(PadState[0][0])); j += 1)
396 {
397 PadState[i][j].open = 0;
398 PadState[i][j].port = 0;
399 PadState[i][j].slot = 0;
400 }
401 }
402
403 switch (padInitialised)
404 {
405 case 1:
406 {
407#if 0
408 int ret;
409 //Unofficial: libpad EE client from v1.3.4 has this RPC function implemented, but is not implemented within its PADMAN module.
410 buffer.command = PAD_RPCCMD_OPEN_OLD;
411 ret = sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL);
412#endif
413 return 1;
414 }
415 case 2:
416 {
417 int ret;
418
419 buffer.command = PAD_RPCCMD_INIT;
420 buffer.padInitArgs.statBuf = openSlot;
421 ret = sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL);
422
423 return ret >= 0 ? buffer.padResult.result : 0;
424 }
425 default:
426 return 1;
427 }
428}
429
430int
432{
433 int ret;
434
435 switch (padInitialised)
436 {
437 case 1:
438 {
439 buffer.command = PAD_RPCCMD_END_OLD;
440 break;
441 }
442 case 2:
443 {
444 buffer.command = PAD_RPCCMD_END_NEW;
445 break;
446 }
447 default:
448 return -1;
449 }
450
451 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
452 return -1;
453
454 ret = buffer.padResult.result;
455 if (ret == 1)
456 padInitialised = 0;
457
458 return ret;
459}
460
461int
462padPortOpen(int port, int slot, void *padArea)
463{
464 union pad_data_u *dma_buf = (union pad_data_u *)padArea;
465
466 if ((unsigned int)port >= (sizeof(PadState)/sizeof(PadState[0])))
467 return 0;
468 if ((unsigned int)slot >= (sizeof(PadState[0])/sizeof(PadState[0][0])))
469 return 0;
470
471 switch (padInitialised)
472 {
473 case 1:
474 {
475 // Check 16 byte alignment
476 if ((u32)padArea & 0xf)
477 {
478 printf("Address is not 16-byte aligned.\n");
479 return 0;
480 }
481 break;
482 }
483 case 2:
484 {
485 // Check 64 byte alignment
486 if ((u32)padArea & 0x3f)
487 {
488 printf("Address is not 64-byte aligned.\n");
489 return 0;
490 }
491 break;
492 }
493 default:
494 return 0;
495 }
496
497
498 // Pad data is double buffered
499 switch (padInitialised)
500 {
501 case 1:
502 {
503 unsigned int i;
504
505 for (i = 0; i < (sizeof(dma_buf->oldPadData)/sizeof(dma_buf->oldPadData[0])); i += 1)
506 {
507 struct pad_data_old *pdata;
508
509 pdata = &dma_buf->oldPadData[i];
510 memset(pdata->data, 0xff, sizeof(pdata->data)); // 'Clear' data area
511 pdata->frame = 0;
512 pdata->length = 0;
513 pdata->state = PAD_STATE_EXECCMD;
514 pdata->reqState = PAD_RSTAT_BUSY;
515 pdata->length = 0;
516 pdata->ok = 0;
517 }
518 break;
519 }
520 case 2:
521 {
522 unsigned int i;
523
524 for (i = 0; i < (sizeof(dma_buf->newPadData)/sizeof(dma_buf->newPadData[0])); i += 1)
525 {
526 struct pad_data_new *pdata;
527
528 pdata = &dma_buf->newPadData[i];
529 memset(pdata->data, 0xff, sizeof(pdata->data)); // 'Clear' data area
530 pdata->frame = 0;
531 pdata->length = 0;
532 pdata->state = PAD_STATE_EXECCMD;
533 pdata->reqState = PAD_RSTAT_BUSY;
534 pdata->length = 0;
535 pdata->currentTask = 0;
536 pdata->buttonDataReady = 0; // Should be cleared in newer padman
537 }
538 break;
539 }
540 default:
541 return 0;
542 }
543
544 switch (padInitialised)
545 {
546 case 1:
547 {
548 buffer.command = PAD_RPCCMD_OPEN_OLD;
549 break;
550 }
551 case 2:
552 {
553 buffer.command = PAD_RPCCMD_OPEN_NEW;
554 break;
555 }
556 default:
557 return 0;
558 }
559 buffer.padOpenArgs.port = port;
560 buffer.padOpenArgs.slot = slot;
561 buffer.padOpenArgs.padArea = padArea;
562
563 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
564 return 0;
565
566 PadState[port][slot].open = padInitialised;
567 PadState[port][slot].padData = padArea;
568 PadState[port][slot].padBuf = buffer.padOpenResult.padBuf;
569
570 return buffer.padOpenResult.result;
571}
572
573int
574padPortClose(int port, int slot)
575{
576 int ret;
577
578 if ((unsigned int)port >= (sizeof(PadState)/sizeof(PadState[0])))
579 return -1;
580 if ((unsigned int)slot >= (sizeof(PadState[0])/sizeof(PadState[0][0])))
581 return -1;
582
583 switch (padInitialised)
584 {
585 case 1:
586 {
587 buffer.command = PAD_RPCCMD_CLOSE_OLD;
588 break;
589 }
590 case 2:
591 {
592 buffer.command = PAD_RPCCMD_CLOSE_NEW;
593 break;
594 }
595 default:
596 return -1;
597 }
598
599 buffer.padCloseArgs.port = port;
600 buffer.padCloseArgs.slot = slot;
601 buffer.padCloseArgs.mode = 1;
602
603 ret = sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL);
604
605 if (ret < 0)
606 return ret;
607 PadState[port][slot].open = 0;
608 return buffer.padResult.result;
609}
610
611unsigned char
612padRead(int port, int slot, struct padButtonStatus *data)
613{
614 if ((unsigned int)port >= (sizeof(PadState)/sizeof(PadState[0])))
615 return 0;
616 if ((unsigned int)slot >= (sizeof(PadState[0])/sizeof(PadState[0][0])))
617 return 0;
618
619 switch (PadState[port][slot].open)
620 {
621 case 1:
622 {
623 struct pad_data_old *pdata;
624
625 pdata = padGetDmaStrOld(port, slot);
626
627 memcpy(data, pdata->data, pdata->length);
628 return pdata->length;
629 }
630 case 2:
631 {
632 struct pad_data_new *pdata;
633
634 pdata = padGetDmaStrNew(port, slot);
635
636 memcpy(data, pdata->data, pdata->length);
637 return pdata->length;
638 }
639 default:
640 return 0;
641 }
642}
643
644int
645padGetState(int port, int slot)
646{
647 if ((unsigned int)port >= (sizeof(PadState)/sizeof(PadState[0])))
648 return 0;
649 if ((unsigned int)slot >= (sizeof(PadState[0])/sizeof(PadState[0][0])))
650 return 0;
651
652 switch (PadState[port][slot].open)
653 {
654 case 1:
655 {
656 const struct pad_data_old *pdata;
657 unsigned char state;
658
659 pdata = padGetDmaStrOld(port, slot);
660 state = pdata->state;
661
662 if (state == PAD_STATE_STABLE && padGetReqState(port, slot) == PAD_RSTAT_BUSY) // Ok
663 return PAD_STATE_EXECCMD;
664 return state;
665 }
666 case 2:
667 {
668 const struct pad_data_new *pdata;
669 unsigned char state;
670
671 pdata = padGetDmaStrNew(port, slot);
672 state = pdata->state;
673
674 if (state == PAD_STATE_ERROR && pdata->findPadRetries)
675 return PAD_STATE_FINDPAD;
676
677 if (state == PAD_STATE_STABLE && padGetReqState(port, slot) == PAD_RSTAT_BUSY) // Ok
678 return PAD_STATE_EXECCMD;
679 return state;
680 }
681 default:
682 return 0;
683 }
684}
685
686unsigned char
687padGetReqState(int port, int slot)
688{
689 if ((unsigned int)port >= (sizeof(PadState)/sizeof(PadState[0])))
690 return 0;
691 if ((unsigned int)slot >= (sizeof(PadState[0])/sizeof(PadState[0][0])))
692 return 0;
693
694 switch (PadState[port][slot].open)
695 {
696 case 1:
697 return padGetDmaStrOld(port, slot)->reqState;
698 case 2:
699 return padGetDmaStrNew(port, slot)->reqState;
700 default:
701 return 0;
702 }
703}
704
705int
706padSetReqState(int port, int slot, int state)
707{
708 if ((unsigned int)port >= (sizeof(PadState)/sizeof(PadState[0])))
709 return 0;
710 if ((unsigned int)slot >= (sizeof(PadState[0])/sizeof(PadState[0][0])))
711 return 0;
712
713 switch (PadState[port][slot].open)
714 {
715 case 1:
716 padGetDmaStrOld(port, slot)->reqState = state;
717 return 1;
718 case 2:
719 padGetDmaStrNew(port, slot)->reqState = state;
720 return 1;
721 default:
722 return 0;
723 }
724}
725
726void
727padStateInt2String(int state, char buf[16])
728{
729 if ((unsigned int)state < (sizeof(padStateString)/sizeof(padStateString[0])))
730 strcpy(buf, padStateString[state]);
731}
732
733void
734padReqStateInt2String(int state, char buf[16])
735{
736 if ((unsigned int)state < (sizeof(padReqStateString)/sizeof(padReqStateString[0])))
737 strcpy(buf, padReqStateString[state]);
738}
739
740int
742{
743 switch (padInitialised)
744 {
745 case 1:
746 {
747 buffer.command = PAD_RPCCMD_GET_PORTMAX_OLD;
748 break;
749 }
750 case 2:
751 {
752 buffer.command = PAD_RPCCMD_GET_PORTMAX_NEW;
753 break;
754 }
755 default:
756 return -1;
757 }
758
759 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
760 return -1;
761
762 return buffer.padResult.result;
763}
764
765int
767{
768 switch (padInitialised)
769 {
770 case 1:
771 {
772 buffer.command = PAD_RPCCMD_GET_SLOTMAX_OLD;
773 break;
774 }
775 case 2:
776 {
777 buffer.command = PAD_RPCCMD_GET_SLOTMAX_NEW;
778 break;
779 }
780 default:
781 return -1;
782 }
783 buffer.padSlotMaxArgs.port = port;
784
785 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
786 return -1;
787
788 return buffer.padResult.result;
789}
790
791int
793{
794 if (padInitialised != 2)
795 return 1; // Well.. return a low version #
796 buffer.command = PAD_RPCCMD_GET_MODVER;
797
798 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
799 return -1;
800
801 return buffer.padResult.result;
802}
803
804int
805padInfoMode(int port, int slot, int infoMode, int index)
806{
807 if ((unsigned int)port >= (sizeof(PadState)/sizeof(PadState[0])))
808 return 0;
809 if ((unsigned int)slot >= (sizeof(PadState[0])/sizeof(PadState[0][0])))
810 return 0;
811
812 switch (PadState[port][slot].open)
813 {
814 case 1:
815 {
816 buffer.command = PAD_RPCCMD_INFO_MODE;
817 buffer.padInfoModeArgs.port = port;
818 buffer.padInfoModeArgs.slot = slot;
819 buffer.padInfoModeArgs.infoMode = infoMode;
820 buffer.padInfoModeArgs.index = index;
821
822 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
823 return 0;
824
825 if (buffer.padModeResult.result == 1)
826 padSetReqState(port, slot, PAD_RSTAT_BUSY);
827 return buffer.padModeResult.result;
828 }
829 case 2:
830 {
831 struct pad_data_new *pdata;
832
833 pdata = padGetDmaStrNew(port, slot);
834
835 if (pdata->currentTask != 1)
836 return 0;
837 if (pdata->reqState == PAD_RSTAT_BUSY)
838 return 0;
839
840 switch (infoMode)
841 {
842 case PAD_MODECURID:
843 return (pdata->modeCurId == 0xF3) ? 0 : (pdata->modeCurId >> 4);
844 case PAD_MODECUREXID:
845 return (pdata->modeConfig == pdata->currentTask || ((unsigned int)(pdata->modeCurOffs) >= (sizeof(pdata->modeTable)/sizeof(pdata->modeTable[0])))) ? 0 : pdata->modeTable[pdata->modeCurOffs];
846 case PAD_MODECUROFFS:
847 return (pdata->modeConfig == 0) ? 0 : pdata->modeCurOffs;
848 case PAD_MODETABLE:
849 if (pdata->modeConfig != 0) {
850 if (index == -1)
851 return pdata->nrOfModes;
852 else if (index < pdata->nrOfModes && ((unsigned int)index <= (sizeof(pdata->modeTable)/sizeof(pdata->modeTable[0]))))
853 return pdata->modeTable[index];
854 }
855 return 0;
856 default:
857 return 0;
858 }
859 }
860 default:
861 return 0;
862 }
863}
864
865int
866padSetMainMode(int port, int slot, int mode, int lock)
867{
868 switch (padInitialised)
869 {
870 case 1:
871 {
872 buffer.command = PAD_RPCCMD_SET_MMODE_OLD;
873 break;
874 }
875 case 2:
876 {
877 buffer.command = PAD_RPCCMD_SET_MMODE_NEW;
878 break;
879 }
880 default:
881 return -1;
882 }
883 buffer.padSetMainModeArgs.port = port;
884 buffer.padSetMainModeArgs.slot = slot;
885 buffer.padSetMainModeArgs.mode = mode;
886 buffer.padSetMainModeArgs.lock = lock;
887
888 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
889 return 0;
890
891 if (buffer.padModeResult.result == 1)
892 padSetReqState(port, slot, PAD_RSTAT_BUSY);
893 return buffer.padModeResult.result;
894}
895
896int
897padInfoPressMode(int port, int slot)
898{
899 return (padGetButtonMask(port, slot) ^ 0x3ffff) ? 0 : 1;
900}
901
902int
903padEnterPressMode(int port, int slot)
904{
905 return padSetButtonInfo(port, slot, 0xFFF);
906}
907
908int
909padExitPressMode(int port, int slot)
910{
911 return padSetButtonInfo(port, slot, 0);
912}
913
914int
915padGetButtonMask(int port, int slot)
916{
917 switch (padInitialised)
918 {
919 case 1:
920 {
921 buffer.command = PAD_RPCCMD_GET_BTNMASK_OLD;
922 break;
923 }
924 case 2:
925 {
926 buffer.command = PAD_RPCCMD_GET_BTNMASK_NEW;
927 break;
928 }
929 default:
930 return -1;
931 }
932 buffer.padGetButtonMaskArgs.port = port;
933 buffer.padGetButtonMaskArgs.slot = slot;
934
935 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
936 return 0;
937
938 return buffer.padResult.result;
939}
940
941int
942padSetButtonInfo(int port, int slot, int buttonInfo)
943{
944 switch (padInitialised)
945 {
946 case 1:
947 {
948 buffer.command = PAD_RPCCMD_SET_BTNINFO_OLD;
949 break;
950 }
951 case 2:
952 {
953 buffer.command = PAD_RPCCMD_SET_BTNINFO_NEW;
954 break;
955 }
956 default:
957 return -1;
958 }
959 buffer.padSetButtonInfoArgs.port = port;
960 buffer.padSetButtonInfoArgs.slot = slot;
961 buffer.padSetButtonInfoArgs.buttonInfo = buttonInfo;
962
963 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
964 return 0;
965
966 if (buffer.padSetButtonInfoResult.result == 1)
967 padSetReqState(port, slot, PAD_RSTAT_BUSY);
968 return buffer.padSetButtonInfoResult.result;
969}
970
971unsigned char
972padInfoAct(int port, int slot, int actuator, int cmd)
973{
974 if ((unsigned int)port >= (sizeof(PadState)/sizeof(PadState[0])))
975 return 0;
976 if ((unsigned int)slot >= (sizeof(PadState[0])/sizeof(PadState[0][0])))
977 return 0;
978
979 switch (PadState[port][slot].open)
980 {
981 case 1:
982 {
983 buffer.command = PAD_RPCCMD_INFO_ACT;
984 buffer.padInfoActArgs.port = port;
985 buffer.padInfoActArgs.slot = slot;
986 buffer.padInfoActArgs.actuator = actuator;
987 buffer.padInfoActArgs.act_cmd = cmd;
988
989 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
990 return 0;
991
992 if (buffer.padModeResult.result == 1)
993 padSetReqState(port, slot, PAD_RSTAT_BUSY);
994 return buffer.padModeResult.result;
995 }
996 case 2:
997 {
998 struct pad_data_new *pdata;
999
1000 pdata = padGetDmaStrNew(port, slot);
1001
1002 if (pdata->currentTask != 1)
1003 return 0;
1004 if (pdata->modeConfig < 2)
1005 return 0;
1006 if (actuator >= pdata->nrOfActuators)
1007 return 0;
1008
1009 if (actuator == -1)
1010 return pdata->nrOfActuators; // # of acutators?
1011
1012 if ((unsigned int)actuator >= (sizeof(pdata->actData)/sizeof(pdata->actData[0])))
1013 return 0;
1014 if ((unsigned int)cmd >= (sizeof(pdata->actData[0])/sizeof(pdata->actData[0][0])))
1015 return 0;
1016
1017 return pdata->actData[actuator][cmd];
1018 }
1019 default:
1020 return 0;
1021 }
1022}
1023
1024int
1025padSetActAlign(int port, int slot, const char actAlign[6])
1026{
1027 switch (padInitialised)
1028 {
1029 case 1:
1030 {
1031 buffer.command = PAD_RPCCMD_SET_ACTALIGN_OLD;
1032 break;
1033 }
1034 case 2:
1035 {
1036 buffer.command = PAD_RPCCMD_SET_ACTALIGN_NEW;
1037 break;
1038 }
1039 default:
1040 return -1;
1041 }
1042 buffer.padActDirAlignArgs.port = port;
1043 buffer.padActDirAlignArgs.slot = slot;
1044
1045 memcpy(buffer.padActDirAlignArgs.align, actAlign, sizeof(buffer.padActDirAlignArgs.align));
1046
1047 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
1048 return 0;
1049
1050 if (buffer.padModeResult.result == 1)
1051 padSetReqState(port, slot, PAD_RSTAT_BUSY);
1052 return buffer.padModeResult.result;
1053}
1054
1055int
1056padSetActDirect(int port, int slot, const char actAlign[6])
1057{
1058 switch (padInitialised)
1059 {
1060 case 1:
1061 {
1062 buffer.command = PAD_RPCCMD_SET_ACTDIR_OLD;
1063 break;
1064 }
1065 case 2:
1066 {
1067 buffer.command = PAD_RPCCMD_SET_ACTDIR_NEW;
1068 break;
1069 }
1070 default:
1071 return -1;
1072 }
1073 buffer.padActDirAlignArgs.port = port;
1074 buffer.padActDirAlignArgs.slot = slot;
1075
1076 memcpy(buffer.padActDirAlignArgs.align, actAlign, sizeof(buffer.padActDirAlignArgs.align));
1077
1078 if (sceSifCallRpc(&padsif[0], 1, 0, &buffer, sizeof(buffer), &buffer, sizeof(buffer), NULL, NULL) < 0)
1079 return 0;
1080
1081 return buffer.padModeResult.result;
1082}
1083
1084/*
1085 * This seems to have been removed from the official SDKs, very early during the PS2's lifetime.
1086 */
1087int
1088padGetConnection(int port, int slot)
1089{
1090 struct open_slot* oslt;
1091
1092 if (padInitialised != 2)
1093 return 1;
1094 oslt = padGetConnDmaStr();
1095 if ((unsigned int)slot >= (sizeof(oslt->openSlots)/sizeof(oslt->openSlots[0])))
1096 return 1;
1097 return ((oslt->openSlots[port] >> slot) & 0x1);
1098}
typedef __attribute__
Definition tlbfunc.c:60
int padGetPortMax(void)
Definition libpad.c:741
int padPortOpen(int port, int slot, void *padArea)
Definition libpad.c:462
int padPortInit(int mode)
Definition libpad.c:386
unsigned char padRead(int port, int slot, struct padButtonStatus *data)
Definition libpad.c:612
int padInfoMode(int port, int slot, int infoMode, int index)
Definition libpad.c:805
unsigned char padInfoAct(int port, int slot, int actuator, int cmd)
Definition libpad.c:972
int padExitPressMode(int port, int slot)
Definition libpad.c:909
int padGetModVersion()
Definition libpad.c:792
int padInit(int mode)
Definition libpad.c:300
int padGetConnection(int port, int slot)
Definition libpad.c:1088
int padSetActDirect(int port, int slot, const char actAlign[6])
Definition libpad.c:1056
int padSetReqState(int port, int slot, int state)
Definition libpad.c:706
int padPortClose(int port, int slot)
Definition libpad.c:574
int padEnd(void)
Definition libpad.c:431
int padGetState(int port, int slot)
Definition libpad.c:645
unsigned char padGetReqState(int port, int slot)
Definition libpad.c:687
static struct pad_data_new * padGetDmaStrNew(int port, int slot)
Definition libpad.c:255
u8 correction
Definition libpad.c:115
static struct open_slot * padGetConnDmaStr(void)
Definition libpad.c:281
int padInfoPressMode(int port, int slot)
Definition libpad.c:897
int padSetMainMode(int port, int slot, int mode, int lock)
Definition libpad.c:866
int padEnterPressMode(int port, int slot)
Definition libpad.c:903
int padGetSlotMax(int port)
Definition libpad.c:766
int padSetActAlign(int port, int slot, const char actAlign[6])
Definition libpad.c:1025