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