PS2SDK
PS2 Homebrew Libraries
padMiscFuncs.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 Lukasz Bruun <mail@lukasz.dk>
3  *
4  * See the file LICENSE included with this distribution for licensing terms.
5  */
6 
12 #include "types.h"
13 #include "freepad.h"
14 #include "stdio.h"
15 #ifdef BUILDING_XPADMAN
16 #include "xsio2man.h"
17 #endif
18 #include "sio2Cmds.h"
19 #include "sysmem.h"
20 #include "thevent.h"
21 #include "thbase.h"
22 #include "vblank.h"
23 #include "irx.h"
24 
25 // Global variables
26 extern struct irx_id _irx_id;
27 
28 extern padState_t padState[2][4];
29 extern u32 openSlots[2];
30 extern vblankData_t vblankData;
31 extern int padman_init;
32 extern void *pad_ee_addr;
33 
34 void DeleteThreadsEventFlag(vblankData_t *s)
35 {
36  DeleteThread(s->tid_1);
37  DeleteThread(s->tid_2);
38  DeleteEventFlag(s->eventflag);
39 }
40 
41 s32 padEnd(void)
42 {
43  if(padman_init != 0)
44  {
45  int port,slot;
46 
47  for(port = 0; port < 2; port++)
48  for(slot=0; slot < 4; slot++)
49  {
50  if((openSlots[port] >> slot) & 0x1)
51  padPortClose(port, slot, 1);
52  }
53 
54  SetEventFlag(vblankData.eventflag, EF_EXIT_THREAD);
55 
56  vblankData.padEnd = 1;
57 
58  WaitEventFlag(vblankData.eventflag, EF_VB_WAIT_THREAD_EXIT, 0x11, 0);
59 
60  DeleteThreadsEventFlag( &vblankData );
61 
62  while(ReleaseVblankHandler(0, (void*)VblankStart) != 0)
63  M_PRINTF("Release VB_START failed.\n");
64 
65  while(ReleaseVblankHandler(1, VblankEnd) != 0)
66  M_PRINTF("Release VB_END failed.\n");
67 
68  pad_ee_addr = NULL;
69  padman_init = 0;
70  }
71 
72  return 1;
73 }
74 
75 s32 padPortClose(s32 port, s32 slot, s32 wait)
76 {
77  if(((openSlots[port] >> slot) & 1) == 0)
78  {
79  M_PRINTF("padPortClose: Port %i Slot %i is not open.\n", (int)port, (int)slot);
80  return 0;
81  }
82 
83  if(padState[port][slot].reqState == PAD_RSTAT_BUSY)
84  {
85  M_PRINTF("padPortClose: Port %i Slot %i request failed.\n", (int)port, (int)slot);
86  return 0;
87  }
88 
89  padState[port][slot].runTask = TASK_PORT_CLOSE;
90  padState[port][slot].taskTid = 0;
91  padState[port][slot].reqState = PAD_RSTAT_BUSY;
92 
93  if(wait)
94  {
95  u32 resbits;
96 
97  WaitEventFlag(padState[port][slot].eventflag, EF_PORT_CLOSE, 0x10, &resbits);
98  DeleteEventFlag(padState[port][slot].eventflag);
99  padState[port][slot].eventflag = 0;
100  }
101 
102  return 1;
103 }
104 
105 u32 padSetMainMode(u32 port, u32 slot, u32 mode, u32 lock)
106 {
107  if( (padState[port][slot].currentTask != TASK_UPDATE_PAD) || ( padState[port][slot].modeConfig < MODE_CONFIG_READY) )
108  return 0;
109 
110  if( mode >= padState[port][slot].numModes )
111  return 0;
112 
113  if( padState[port][slot].reqState != PAD_RSTAT_BUSY)
114  {
115  padState[port][slot].mode = mode;
116  padState[port][slot].lock = lock;
117  padState[port][slot].runTask = TASK_SET_MAIN_MODE;
118  padState[port][slot].reqState = PAD_RSTAT_BUSY;
119  padState[port][slot].taskTid = padState[port][slot].setmainmodeTid;
120 
121  return 1;
122  }
123 
124  return 0;
125 }
126 
127 s32 padInfoAct(u32 port, u32 slot, s32 act, u32 val)
128 {
129  if(padState[port][slot].currentTask != TASK_UPDATE_PAD)
130  return 0;
131 
132  if(padState[port][slot].modeConfig < MODE_CONFIG_READY)
133  return -1;
134 
135  if(act == -1) return padState[port][slot].numActuators;
136 
137  if( act < padState[port][slot].numActuators )
138  {
139  u8 *actData = padState[port][slot].actData.data[act];
140 
141  switch(val)
142  {
143  case 1:
144  return actData[0];
145  case 2:
146  return actData[1];
147  case 3:
148  return actData[2];
149  case 4:
150  return actData[3];
151  }
152  }
153 
154  return -1;
155 }
156 
157 s32 padInfoComb(u32 port, u32 slot, s32 listno, u32 offs)
158 {
159  if(padState[port][slot].currentTask != TASK_UPDATE_PAD)
160  return 0;
161 
162  if(padState[port][slot].modeConfig < MODE_CONFIG_READY)
163  return -1;
164 
165  if(listno == -1) return padState[port][slot].numActComb;
166 
167  if( listno < padState[port][slot].numActComb)
168  {
169  u8 *combData = padState[port][slot].combData.data[listno];
170 
171  switch(offs)
172  {
173  case -1:
174  return combData[0];
175  case 0:
176  return combData[1];
177  case 1:
178  return combData[2];
179  case 2:
180  return combData[3];
181  }
182  }
183 
184  return -1;
185 }
186 
187 s32 padInfoMode(u32 port, u32 slot, s32 term, u32 offs)
188 {
189  if((padState[port][slot].currentTask != TASK_UPDATE_PAD) || (padState[port][slot].reqState == PAD_RSTAT_BUSY))
190  return 0;
191 
192  switch(term)
193  {
194  case 2:
195  if(padState[port][slot].modeConfig == MODE_CONFIG_QUERY_PAD)
196  return 0;
197  else
198  return padState[port][slot].modeTable.data[padState[port][slot].modeCurOffs];
199  case 1:
200  if( padState[port][slot].modeCurId != PAD_ID_CONFIG)
201  return (PAD_ID_HI(PAD_ID_CONFIG));
202  else
203  return 0;
204  case 3:
205  if(padState[port][slot].modeConfig == MODE_CONFIG_QUERY_PAD)
206  return 0;
207  else
208  return padState[port][slot].modeCurOffs;
209  case 4:
210  if(padState[port][slot].modeConfig == MODE_CONFIG_QUERY_PAD)
211  return 0;
212  else
213  {
214  if(offs == (u32)(-1))
215  {
216  return padState[port][slot].numModes;
217  }
218  else
219  {
220  u16* mode = padState[port][slot].modeTable.data;
221 
222  if(offs < padState[port][slot].numModes)
223  return mode[offs];
224  else
225  return 0;
226  }
227  }
228  }
229 
230  return -1;
231 }
232 
233 u32 ActDirectTotal(u32 port, u32 slot)
234 {
235  u32 ret = 0;
236  u32 p, s;
237 
238  for(p = 0; p < padGetPortMax(); p++)
239  {
240  for(s = 0; s < padGetSlotMax(port); s++)
241  {
242  if( (p == port) && (s == slot) && (((openSlots[port] >> slot) & 1) != 0))
243  {
244  if(padState[port][slot].modeCurId != 0)
245  {
246  int i;
247 
248  for(i=0; i < padState[port][slot].ee_actDirectSize; i++)
249  {
250  if((padState[port][slot].ee_actAlignData.data[i] != 0xFF)
251  && (padState[port][slot].ee_actDirectData.data[i] != 0))
252  {
253  u8 *act = padState[port][slot].actData.data[padState[port][slot].ee_actAlignData.data[i]];
254  ret += act[3];
255  }
256  }
257  }
258  }
259  }
260  }
261 
262  return ret;
263 }
264 
265 u32 CheckAirDirectTotal(u32 port, u32 slot, u8 *actData)
266 {
267  int i;
268  u32 total = ActDirectTotal(port, slot);
269 
270  for(i=0; i < 6; i++)
271  {
272  u32 a = padState[port][slot].ee_actAlignData.data[i];
273 
274  if(a != 0xFF)
275  {
276  if( actData[a] != 0 )
277  {
278  u8 *act = padState[port][slot].actData.data[a];
279 
280  total += act[3];
281 
282  if(total >= 0x3D)
283  {
284  M_KPRINTF("Over Consumpt Max 600mA[%d][%d]\n", (int)port, (int)slot);
285  actData[a] = 0;
286  }
287  }
288  }
289  }
290 
291  return 1;
292 }
293 
294 u32 padSetActDirect(u32 port, u32 slot, u8 *actData)
295 {
296  if(padState[port][slot].currentTask == TASK_UPDATE_PAD)
297  {
298  if( CheckAirDirectTotal(port, slot, actData) == 0)
299  { //This doesn't seem to be ever used.
300  M_KPRINTF("Over consumpt Max [%d][%d]\n", (int)port, (int)slot);
301  }
302  else
303  {
304  int i;
305 
306  for(i=0; i < 6; i++)
307  padState[port][slot].ee_actDirectData.data[i] = actData[i];
308 
309  padState[port][slot].ee_actDirectSize = 6;
310 
311  return 1;
312  }
313  }
314 
315  return 0;
316 }
317 
318 u32 padSetActAlign(u32 port, u32 slot, const u8 *actData)
319 {
320  if( (padState[port][slot].currentTask != TASK_UPDATE_PAD) || ( padState[port][slot].modeConfig < MODE_CONFIG_READY) )
321  return 0;
322 
323  if( padState[port][slot].reqState != PAD_RSTAT_BUSY)
324  {
325  int i;
326 
327  for(i=0; i < 6; i++)
328  padState[port][slot].ee_actAlignData.data[i] = actData[i];
329 
330  padState[port][slot].reqState = PAD_RSTAT_BUSY;
331  padState[port][slot].runTask = TASK_SET_ACT_ALIGN;
332  padState[port][slot].taskTid = padState[port][slot].setactalignTid;
333 
334  return 1;
335  }
336 
337  return 0;
338 }
339 
340 u32 padGetButtonMask(u32 port, u32 slot)
341 {
342  u32 ret = 0;
343 
344  if( (padState[port][slot].currentTask != TASK_UPDATE_PAD) || ( padState[port][slot].modeConfig < MODE_CONFIG_READY) )
345  return ret;
346 
347  if( padState[port][slot].model < 2)
348  return ret;
349 
350  ret = (u32)padState[port][slot].buttonMask[0];
351  ret |= (u32)padState[port][slot].buttonMask[1] << 8;
352  ret |= (u32)padState[port][slot].buttonMask[2] << 16;
353  ret |= (u32)padState[port][slot].buttonMask[3] << 24;
354 
355  return ret;
356 }
357 
358 u32 padSetButtonInfo(u32 port, u32 slot, u32 info)
359 {
360  if( (padState[port][slot].currentTask != TASK_UPDATE_PAD) || ( padState[port][slot].modeConfig < MODE_CONFIG_READY) )
361  return 0;
362 
363  if( padState[port][slot].model < 2)
364  return 0;
365 
366  if( padState[port][slot].reqState != PAD_RSTAT_BUSY)
367  {
368  int i;
369 
370  info = (info << 6) | 0x3F;
371 
372  padState[port][slot].buttonInfo[0] = (u8)(info);
373  padState[port][slot].buttonInfo[1] = (u8)(info >> 8);
374  padState[port][slot].buttonInfo[2] = (u8)(info >> 16);
375  padState[port][slot].buttonInfo[3] = (u8)(info >> 24);
376 
377  for(i=0; i < 11; i++)
378  padState[port][slot].modeParam[i] = 0x2;
379 
380  padState[port][slot].reqState = PAD_RSTAT_BUSY;
381  padState[port][slot].runTask = TASK_SET_BUTTON_INFO;
382  padState[port][slot].taskTid = padState[port][slot].setbuttoninfoTid;
383 
384  return 1;
385  }
386 
387 
388  return 0;
389 }
390 
391 u32 padSetVrefParam(u32 port, u32 slot, const u8 *vparam)
392 {
393  if( (padState[port][slot].currentTask != TASK_UPDATE_PAD) || ( padState[port][slot].modeConfig < MODE_CONFIG_READY) )
394  return 0;
395 
396  if( padState[port][slot].model < 2)
397  return 0;
398 
399  if( padState[port][slot].reqState != PAD_RSTAT_BUSY)
400  {
401  int i;
402 
403  for(i=0; i < 12; i++)
404  padState[port][slot].modeParam[i] = vparam[i];
405 
406  padState[port][slot].runTask = TASK_SET_VREF_PARAM;
407  padState[port][slot].reqState = PAD_RSTAT_BUSY;
408  padState[port][slot].taskTid = padState[port][slot].setvrefparamTid;
409 
410  return 1;
411  }
412 
413  return 0;
414 }
415 
416 u32 padGetPortMax(void)
417 {
418  return 2;
419 }
420 
421 u32 padGetSlotMax(u32 port)
422 {
423 #ifdef BUILDING_XPADMAN
424  return sio2_mtap_get_slot_max(port);
425 #else
426  return 1;
427 #endif
428 }
429 
431 {
432  return _irx_id.v;
433 }
434 
435 u32 padGetInBuffer(u32 port, u32 slot, u8 *buf)
436 {
437  int i;
438 
439  for(i=0; i < 32 ; i++)
440  buf[i] = padState[port][slot].inbuffer[i];
441 
442  return 32;
443 }
444 
445 u32 padGetModeConfig(u32 port, u32 slot)
446 {
447  return padState[port][slot].modeConfig;
448 }
padGetPortMax
u32 padGetPortMax(void)
Definition: padMiscFuncs.c:416
xsio2man.h
thbase.h
padPortClose
int padPortClose(int port, int slot)
Definition: libpad.c:574
s_info
Definition: xprintf.c:78
vblankData_t
Definition: freepad.h:97
padState_t
Definition: freepad.h:158
padSetActAlign
int padSetActAlign(int port, int slot, const char actAlign[6])
Definition: libpad.c:1025
irx_id
Definition: irx.h:27
irx.h
padInfoMode
int padInfoMode(int port, int slot, int infoMode, int index)
Definition: libpad.c:805
padGetSlotMax
int padGetSlotMax(int port)
Definition: libpad.c:766
vblank.h
stdio.h
freepad.h
sysmem.h
padSetMainMode
int padSetMainMode(int port, int slot, int mode, int lock)
Definition: libpad.c:866
padSetActDirect
int padSetActDirect(int port, int slot, const char actAlign[6])
Definition: libpad.c:1056
padEnd
s32 padEnd(void)
Definition: padMiscFuncs.c:41
padGetModVersion
u32 padGetModVersion(void)
Definition: padMiscFuncs.c:430
padInfoAct
unsigned char padInfoAct(int port, int slot, int actuator, int cmd)
Definition: libpad.c:972
thevent.h
sio2Cmds.h