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 "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;
113  u8 model;
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 
126 struct pad_state
127 {
128  int open;
129  unsigned int port;
130  unsigned int slot;
131  union pad_data_u *padData;
132  unsigned char *padBuf;
133 };
134 
135 struct open_slot
136 {
137  u32 frame;
138  u32 openSlots[2];
139  u8 padding[116];
140 };
141 
142 extern int _iop_reboot_count;
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 
254 static struct pad_data_new*
255 padGetDmaStrNew(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 
265 static struct pad_data_old*
266 padGetDmaStrOld(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 
280 static 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 
299 int
300 padInit(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 
386 int 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 
430 int
431 padEnd(void)
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 
461 int
462 padPortOpen(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 
573 int
574 padPortClose(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 
611 unsigned char
612 padRead(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 
644 int
645 padGetState(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 
686 unsigned char
687 padGetReqState(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 
705 int
706 padSetReqState(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 
726 void
727 padStateInt2String(int state, char buf[16])
728 {
729  if ((unsigned int)state < (sizeof(padStateString)/sizeof(padStateString[0])))
730  strcpy(buf, padStateString[state]);
731 }
732 
733 void
734 padReqStateInt2String(int state, char buf[16])
735 {
736  if ((unsigned int)state < (sizeof(padReqStateString)/sizeof(padReqStateString[0])))
737  strcpy(buf, padReqStateString[state]);
738 }
739 
740 int
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 
765 int
766 padGetSlotMax(int port)
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 
791 int
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 
804 int
805 padInfoMode(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 
865 int
866 padSetMainMode(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 
896 int
897 padInfoPressMode(int port, int slot)
898 {
899  return (padGetButtonMask(port, slot) ^ 0x3ffff) ? 0 : 1;
900 }
901 
902 int
903 padEnterPressMode(int port, int slot)
904 {
905  return padSetButtonInfo(port, slot, 0xFFF);
906 }
907 
908 int
909 padExitPressMode(int port, int slot)
910 {
911  return padSetButtonInfo(port, slot, 0);
912 }
913 
914 int
915 padGetButtonMask(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 
941 int
942 padSetButtonInfo(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 
971 unsigned char
972 padInfoAct(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 
1024 int
1025 padSetActAlign(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 
1055 int
1056 padSetActDirect(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  */
1087 int
1088 padGetConnection(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 }
kernel.h
padInfoAct
unsigned char padInfoAct(int port, int slot, int actuator, int cmd)
Definition: libpad.c:972
padGetState
int padGetState(int port, int slot)
Definition: libpad.c:645
padGetDmaStrNew
static struct pad_data_new * padGetDmaStrNew(int port, int slot)
Definition: libpad.c:255
libpad.h
pad_data_old::model
u8 model
Definition: libpad.c:113
padPortClose
int padPortClose(int port, int slot)
Definition: libpad.c:574
request
Definition: thread.c:17
padGetPortMax
int padGetPortMax(void)
Definition: libpad.c:741
padInit
int padInit(int mode)
Definition: libpad.c:300
padGetReqState
unsigned char padGetReqState(int port, int slot)
Definition: libpad.c:687
padPortOpen
int padPortOpen(int port, int slot, void *padArea)
Definition: libpad.c:462
padGetConnDmaStr
static struct open_slot * padGetConnDmaStr(void)
Definition: libpad.c:281
padSetActAlign
int padSetActAlign(int port, int slot, const char actAlign[6])
Definition: libpad.c:1025
padGetSlotMax
int padGetSlotMax(int port)
Definition: libpad.c:766
pad_data_old::CTP
u8 CTP
Definition: libpad.c:111
padSetReqState
int padSetReqState(int port, int slot, int state)
Definition: libpad.c:706
pad_data_old
Definition: libpad.c:100
padInfoPressMode
int padInfoPressMode(int port, int slot)
Definition: libpad.c:897
padRead
unsigned char padRead(int port, int slot, struct padButtonStatus *data)
Definition: libpad.c:612
pad_data_new
Definition: libpad.c:69
padInfoMode
int padInfoMode(int port, int slot, int infoMode, int index)
Definition: libpad.c:805
padGetConnection
int padGetConnection(int port, int slot)
Definition: libpad.c:1088
_iop_reboot_count
int _iop_reboot_count
padEnd
int padEnd(void)
Definition: libpad.c:431
open_slot
Definition: libpad.c:135
tamtypes.h
stdio.h
pad_data_old::correction
u8 correction
Definition: libpad.c:115
padPortInit
int padPortInit(int mode)
Definition: libpad.c:386
padEnterPressMode
int padEnterPressMode(int port, int slot)
Definition: libpad.c:903
padExitPressMode
int padExitPressMode(int port, int slot)
Definition: libpad.c:909
t_SifRpcClientData
Definition: sifrpc-common.h:134
padGetModVersion
int padGetModVersion()
Definition: libpad.c:792
__attribute__
Definition: gif_registers.h:38
padSetActDirect
int padSetActDirect(int port, int slot, const char actAlign[6])
Definition: libpad.c:1056
pad_state
Definition: libpad.c:126
__attribute__
static SifRpcClientData_t padsif[2] __attribute__((aligned(64)))
padSetMainMode
int padSetMainMode(int port, int slot, int mode, int lock)
Definition: libpad.c:866
pad_data_u
Definition: libpad.c:120
padButtonStatus
Definition: libpad.h:95