1 /* Copyright 2005 Guillaume Duhamel
2 Copyright 2005-2006, 2013 Theo Berkau
3
4 This file is part of Yabause.
5
6 Yabause is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 Yabause is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Yabause; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /*! \file peripheral.c
22 \brief Peripheral shared functions.
23 */
24
25 #include "debug.h"
26 #include "peripheral.h"
27
28 const char * PerPadNames[] =
29 {
30 "Up",
31 "Right",
32 "Down",
33 "Left",
34 "R",
35 "L",
36 "Start",
37 "A",
38 "B",
39 "C",
40 "X",
41 "Y",
42 "Z",
43 NULL
44 };
45
46 const char * PerMouseNames[] =
47 {
48 "A",
49 "B",
50 "C",
51 "Start",
52 NULL
53 };
54
55 PortData_struct PORTDATA1;
56 PortData_struct PORTDATA2;
57
58 PerInterface_struct * PERCore = NULL;
59 extern PerInterface_struct * PERCoreList[];
60
61 typedef struct {
62 u8 name;
63 void (*Press)(void *);
64 void (*Release)(void *);
65 void (*SetAxisValue)(void *, u32);
66 void (*MoveAxis)(void *, s32, s32);
67 } PerBaseConfig_struct;
68
69 typedef struct {
70 u32 key;
71 PerBaseConfig_struct * base;
72 void * controller;
73 } PerConfig_struct;
74
75 #define PERCB(func) ((void (*) (void *)) func)
76 #define PERVALCB(func) ((void (*) (void *, u32)) func)
77 #define PERMOVECB(func) ((void (*) (void *, s32, s32)) func)
78
79 PerBaseConfig_struct perpadbaseconfig[] = {
80 { PERPAD_UP, PERCB(PerPadUpPressed), PERCB(PerPadUpReleased), NULL, NULL },
81 { PERPAD_RIGHT, PERCB(PerPadRightPressed), PERCB(PerPadRightReleased), NULL, NULL },
82 { PERPAD_DOWN, PERCB(PerPadDownPressed), PERCB(PerPadDownReleased), NULL, NULL },
83 { PERPAD_LEFT, PERCB(PerPadLeftPressed), PERCB(PerPadLeftReleased), NULL, NULL },
84 { PERPAD_RIGHT_TRIGGER, PERCB(PerPadRTriggerPressed), PERCB(PerPadRTriggerReleased), NULL, NULL },
85 { PERPAD_LEFT_TRIGGER, PERCB(PerPadLTriggerPressed), PERCB(PerPadLTriggerReleased), NULL, NULL },
86 { PERPAD_START, PERCB(PerPadStartPressed), PERCB(PerPadStartReleased), NULL, NULL },
87 { PERPAD_A, PERCB(PerPadAPressed), PERCB(PerPadAReleased), NULL, NULL },
88 { PERPAD_B, PERCB(PerPadBPressed), PERCB(PerPadBReleased), NULL, NULL },
89 { PERPAD_C, PERCB(PerPadCPressed), PERCB(PerPadCReleased), NULL, NULL },
90 { PERPAD_X, PERCB(PerPadXPressed), PERCB(PerPadXReleased), NULL, NULL },
91 { PERPAD_Y, PERCB(PerPadYPressed), PERCB(PerPadYReleased), NULL, NULL },
92 { PERPAD_Z, PERCB(PerPadZPressed), PERCB(PerPadZReleased), NULL, NULL },
93 };
94
95 PerBaseConfig_struct permousebaseconfig[] = {
96 { PERMOUSE_LEFT, PERCB(PerMouseLeftPressed), PERCB(PerMouseLeftReleased), NULL, NULL },
97 { PERMOUSE_MIDDLE, PERCB(PerMouseMiddlePressed), PERCB(PerMouseMiddleReleased), NULL, NULL },
98 { PERMOUSE_RIGHT, PERCB(PerMouseRightPressed), PERCB(PerMouseRightReleased), NULL, NULL },
99 { PERMOUSE_START, PERCB(PerMouseStartPressed), PERCB(PerMouseStartReleased), NULL, NULL },
100 { PERMOUSE_AXIS, NULL, NULL, NULL, PERMOVECB(PerMouseMove) },
101 };
102
103 PerBaseConfig_struct peranalogbaseconfig[] = {
104 { PERANALOG_AXIS1, NULL, NULL, PERVALCB(PerAxis1Value), NULL },
105 { PERANALOG_AXIS2, NULL, NULL, PERVALCB(PerAxis2Value), NULL },
106 { PERANALOG_AXIS3, NULL, NULL, PERVALCB(PerAxis3Value), NULL },
107 { PERANALOG_AXIS4, NULL, NULL, PERVALCB(PerAxis4Value), NULL },
108 { PERANALOG_AXIS5, NULL, NULL, PERVALCB(PerAxis5Value), NULL },
109 { PERANALOG_AXIS6, NULL, NULL, PERVALCB(PerAxis6Value), NULL },
110 { PERANALOG_AXIS7, NULL, NULL, PERVALCB(PerAxis7Value), NULL },
111 };
112
113 PerBaseConfig_struct pergunbaseconfig[] = {
114 { PERGUN_TRIGGER, PERCB(PerGunTriggerPressed), PERCB(PerGunTriggerReleased), NULL, NULL },
115 { PERGUN_START, PERCB(PerGunStartPressed), PERCB(PerGunStartReleased), NULL, NULL },
116 { PERGUN_AXIS, NULL, NULL, NULL, PERMOVECB(PerGunMove) },
117 };
118
119 static u32 perkeyconfigsize = 0;
120 static PerConfig_struct * perkeyconfig = NULL;
121
122 static void PerUpdateConfig(PerBaseConfig_struct * baseconfig, int nelems, void * controller);
123
124 //////////////////////////////////////////////////////////////////////////////
125
PerInit(int coreid)126 int PerInit(int coreid) {
127 int i;
128
129 // So which core do we want?
130 if (coreid == PERCORE_DEFAULT)
131 coreid = 0; // Assume we want the first one
132
133 // Go through core list and find the id
134 for (i = 0; PERCoreList[i] != NULL; i++)
135 {
136 if (PERCoreList[i]->id == coreid)
137 {
138 // Set to current core
139 PERCore = PERCoreList[i];
140 break;
141 }
142 }
143
144 if (PERCore == NULL)
145 return -1;
146
147 if (PERCore->Init() != 0)
148 return -1;
149
150 return 0;
151 }
152
153 //////////////////////////////////////////////////////////////////////////////
154
PerDeInit(void)155 void PerDeInit(void) {
156 if (PERCore)
157 PERCore->DeInit();
158 PERCore = NULL;
159 }
160
161 //////////////////////////////////////////////////////////////////////////////
162
PerPadUpPressed(PerPad_struct * pad)163 void PerPadUpPressed(PerPad_struct * pad) {
164 *pad->padbits &= 0xEF;
165 SMPCLOG("Up\n");
166 }
167
168 //////////////////////////////////////////////////////////////////////////////
169
PerPadUpReleased(PerPad_struct * pad)170 void PerPadUpReleased(PerPad_struct * pad) {
171 *pad->padbits |= ~0xEF;
172 }
173
174 //////////////////////////////////////////////////////////////////////////////
175
PerPadDownPressed(PerPad_struct * pad)176 void PerPadDownPressed(PerPad_struct * pad) {
177 *pad->padbits &= 0xDF;
178 SMPCLOG("Down\n");
179 }
180
181 //////////////////////////////////////////////////////////////////////////////
182
PerPadDownReleased(PerPad_struct * pad)183 void PerPadDownReleased(PerPad_struct * pad) {
184 *pad->padbits |= ~0xDF;
185 }
186
187 //////////////////////////////////////////////////////////////////////////////
188
PerPadRightPressed(PerPad_struct * pad)189 void PerPadRightPressed(PerPad_struct * pad) {
190 *pad->padbits &= 0x7F;
191 SMPCLOG("Right\n");
192 }
193
194 //////////////////////////////////////////////////////////////////////////////
195
PerPadRightReleased(PerPad_struct * pad)196 void PerPadRightReleased(PerPad_struct * pad) {
197 *pad->padbits |= ~0x7F;
198 }
199
200 //////////////////////////////////////////////////////////////////////////////
201
PerPadLeftPressed(PerPad_struct * pad)202 void PerPadLeftPressed(PerPad_struct * pad) {
203 *pad->padbits &= 0xBF;
204 SMPCLOG("Left\n");
205 }
206
207 //////////////////////////////////////////////////////////////////////////////
208
PerPadLeftReleased(PerPad_struct * pad)209 void PerPadLeftReleased(PerPad_struct * pad) {
210 *pad->padbits |= ~0xBF;
211 }
212
213 //////////////////////////////////////////////////////////////////////////////
214
PerPadStartPressed(PerPad_struct * pad)215 void PerPadStartPressed(PerPad_struct * pad) {
216 *pad->padbits &= 0xF7;
217 SMPCLOG("Start\n");
218 }
219
220 //////////////////////////////////////////////////////////////////////////////
221
PerPadStartReleased(PerPad_struct * pad)222 void PerPadStartReleased(PerPad_struct * pad) {
223 *pad->padbits |= ~0xF7;
224 }
225
226 //////////////////////////////////////////////////////////////////////////////
227
PerPadAPressed(PerPad_struct * pad)228 void PerPadAPressed(PerPad_struct * pad) {
229 *pad->padbits &= 0xFB;
230 SMPCLOG("A\n");
231 }
232
233 //////////////////////////////////////////////////////////////////////////////
234
PerPadAReleased(PerPad_struct * pad)235 void PerPadAReleased(PerPad_struct * pad) {
236 *pad->padbits |= ~0xFB;
237 }
238
239 //////////////////////////////////////////////////////////////////////////////
240
PerPadBPressed(PerPad_struct * pad)241 void PerPadBPressed(PerPad_struct * pad) {
242 *pad->padbits &= 0xFE;
243 SMPCLOG("B\n");
244 }
245
246 //////////////////////////////////////////////////////////////////////////////
247
PerPadBReleased(PerPad_struct * pad)248 void PerPadBReleased(PerPad_struct * pad) {
249 *pad->padbits |= ~0xFE;
250 }
251
252 //////////////////////////////////////////////////////////////////////////////
253
PerPadCPressed(PerPad_struct * pad)254 void PerPadCPressed(PerPad_struct * pad) {
255 *pad->padbits &= 0xFD;
256 SMPCLOG("C\n");
257 }
258
259 //////////////////////////////////////////////////////////////////////////////
260
PerPadCReleased(PerPad_struct * pad)261 void PerPadCReleased(PerPad_struct * pad) {
262 *pad->padbits |= ~0xFD;
263 }
264
265 //////////////////////////////////////////////////////////////////////////////
266
PerPadXPressed(PerPad_struct * pad)267 void PerPadXPressed(PerPad_struct * pad) {
268 *(pad->padbits + 1) &= 0xBF;
269 SMPCLOG("X\n");
270 }
271
272 //////////////////////////////////////////////////////////////////////////////
273
PerPadXReleased(PerPad_struct * pad)274 void PerPadXReleased(PerPad_struct * pad) {
275 *(pad->padbits + 1) |= ~0xBF;
276 }
277
278 //////////////////////////////////////////////////////////////////////////////
279
PerPadYPressed(PerPad_struct * pad)280 void PerPadYPressed(PerPad_struct * pad) {
281 *(pad->padbits + 1) &= 0xDF;
282 SMPCLOG("Y\n");
283 }
284
285 //////////////////////////////////////////////////////////////////////////////
286
PerPadYReleased(PerPad_struct * pad)287 void PerPadYReleased(PerPad_struct * pad) {
288 *(pad->padbits + 1) |= ~0xDF;
289 }
290
291 //////////////////////////////////////////////////////////////////////////////
292
PerPadZPressed(PerPad_struct * pad)293 void PerPadZPressed(PerPad_struct * pad) {
294 *(pad->padbits + 1) &= 0xEF;
295 SMPCLOG("Z\n");
296 }
297
298 //////////////////////////////////////////////////////////////////////////////
299
PerPadZReleased(PerPad_struct * pad)300 void PerPadZReleased(PerPad_struct * pad) {
301 *(pad->padbits + 1) |= ~0xEF;
302 }
303
304 //////////////////////////////////////////////////////////////////////////////
305
PerPadRTriggerPressed(PerPad_struct * pad)306 void PerPadRTriggerPressed(PerPad_struct * pad) {
307 *(pad->padbits + 1) &= 0x7F;
308 SMPCLOG("Right Trigger\n");
309 }
310
311 //////////////////////////////////////////////////////////////////////////////
312
PerPadRTriggerReleased(PerPad_struct * pad)313 void PerPadRTriggerReleased(PerPad_struct * pad) {
314 *(pad->padbits + 1) |= ~0x7F;
315 }
316
317 //////////////////////////////////////////////////////////////////////////////
318
PerPadLTriggerPressed(PerPad_struct * pad)319 void PerPadLTriggerPressed(PerPad_struct * pad) {
320 *(pad->padbits + 1) &= 0xF7;
321 SMPCLOG("Left Trigger\n");
322 }
323
324 //////////////////////////////////////////////////////////////////////////////
325
PerPadLTriggerReleased(PerPad_struct * pad)326 void PerPadLTriggerReleased(PerPad_struct * pad) {
327 *(pad->padbits + 1) |= ~0xF7;
328 }
329
330 //////////////////////////////////////////////////////////////////////////////
331
PerMouseLeftPressed(PerMouse_struct * mouse)332 void PerMouseLeftPressed(PerMouse_struct * mouse) {
333 *(mouse->mousebits) |= 1;
334 }
335
336 //////////////////////////////////////////////////////////////////////////////
337
PerMouseLeftReleased(PerMouse_struct * mouse)338 void PerMouseLeftReleased(PerMouse_struct * mouse) {
339 *(mouse->mousebits) &= 0xFE;
340 }
341
342 //////////////////////////////////////////////////////////////////////////////
343
PerMouseMiddlePressed(PerMouse_struct * mouse)344 void PerMouseMiddlePressed(PerMouse_struct * mouse) {
345 *(mouse->mousebits) |= 4;
346 }
347
348 //////////////////////////////////////////////////////////////////////////////
349
PerMouseMiddleReleased(PerMouse_struct * mouse)350 void PerMouseMiddleReleased(PerMouse_struct * mouse) {
351 *(mouse->mousebits) &= 0xFFFB;
352 }
353
354 //////////////////////////////////////////////////////////////////////////////
355
PerMouseRightPressed(PerMouse_struct * mouse)356 void PerMouseRightPressed(PerMouse_struct * mouse) {
357 *(mouse->mousebits) |= 2;
358 }
359
360 //////////////////////////////////////////////////////////////////////////////
361
PerMouseRightReleased(PerMouse_struct * mouse)362 void PerMouseRightReleased(PerMouse_struct * mouse) {
363 *(mouse->mousebits) &= 0xFD;
364 }
365
366 //////////////////////////////////////////////////////////////////////////////
367
PerMouseStartPressed(PerMouse_struct * mouse)368 void PerMouseStartPressed(PerMouse_struct * mouse) {
369 *(mouse->mousebits) |= 8;
370 }
371
372 //////////////////////////////////////////////////////////////////////////////
373
PerMouseStartReleased(PerMouse_struct * mouse)374 void PerMouseStartReleased(PerMouse_struct * mouse) {
375 *(mouse->mousebits) &= 0xF7;
376 }
377
378 //////////////////////////////////////////////////////////////////////////////
379
PerMouseMove(PerMouse_struct * mouse,s32 dispx,s32 dispy)380 void PerMouseMove(PerMouse_struct * mouse, s32 dispx, s32 dispy)
381 {
382 int negx, negy, overflowx, overflowy;
383 u8 diffx, diffy;
384
385 negx = ((mouse->mousebits[0] >> 4) & 1);
386 negy = ((mouse->mousebits[0] >> 5) & 1);
387 overflowx = ((mouse->mousebits[0] >> 6) & 1);
388 overflowy = ((mouse->mousebits[0] >> 7) & 1);
389
390 if (negx) diffx = ~(mouse->mousebits[1]) & 0xFF;
391 else diffx = mouse->mousebits[1];
392 if (negy) diffy = ~(mouse->mousebits[2]) & 0xFF;
393 else diffy = mouse->mousebits[2];
394
395 if (dispx >= 0)
396 {
397 if (negx)
398 {
399 if (dispx - diffx > 0)
400 {
401 diffx = dispx - diffx;
402 negx = 0;
403 }
404 else diffx -= -dispx;
405 }
406 else diffx += dispx;
407 }
408 else
409 {
410 if (negx) diffx += -dispx;
411 else
412 {
413 if (diffx + dispx > 0) diffx += dispx;
414 else
415 {
416 diffx = -dispx - diffx;
417 negx = 1;
418 }
419 }
420 }
421
422 if (dispy >= 0)
423 {
424 if (negy)
425 {
426 if (dispy - diffy > 0)
427 {
428 diffy = dispy - diffy;
429 negy = 0;
430 }
431 else diffy -= -dispy;
432 }
433 else diffy += dispy;
434 }
435 else
436 {
437 if (negy) diffy += -dispy;
438 else
439 {
440 if (diffy + dispy > 0) diffy += dispy;
441 else
442 {
443 diffy = -dispy - diffy;
444 negy = 1;
445 }
446 }
447 }
448
449 mouse->mousebits[0] = (overflowy << 7) | (overflowx << 6) | (negy << 5) | (negx << 4) | (mouse->mousebits[0] & 0x0F);
450 if (negx) mouse->mousebits[1] = ~(diffx);
451 else mouse->mousebits[1] = diffx;
452 if (negy) mouse->mousebits[2] = ~(diffy);
453 else mouse->mousebits[2] = diffy;
454 }
455
456 //////////////////////////////////////////////////////////////////////////////
457
PerAxis1Value(PerAnalog_struct * analog,u32 val)458 void PerAxis1Value(PerAnalog_struct * analog, u32 val)
459 {
460 analog->analogbits[2] = (u8)val;
461
462 //handle wheel left/right standard pad presses depending on wheel position
463 if (analog->perid == PERWHEEL)
464 {
465 int left_is_pressed = (analog->analogbits[0] & (1 << 6)) == 0;
466 int right_is_pressed = (analog->analogbits[0] & (1 << 7)) == 0;
467
468 if (val <= 0x67)
469 analog->analogbits[0] &= 0xBF;//press left
470 else if (left_is_pressed && val >= 0x6f)
471 analog->analogbits[0] |= ~0xBF;//release left
472
473
474 if (val >= 0x97)
475 analog->analogbits[0] &= 0x7F;//press right
476 else if(right_is_pressed && val <= 0x8f)
477 analog->analogbits[0] |= ~0x7F;//release right
478 }
479 else if (analog->perid == PERMISSIONSTICK ||
480 analog->perid == PERTWINSTICKS)
481 {
482 int left_is_pressed = (analog->analogbits[0] & (1 << 6)) == 0;
483 int right_is_pressed = (analog->analogbits[0] & (1 << 7)) == 0;
484
485 if (val <= 0x56)
486 analog->analogbits[0] &= 0xBF;//press left
487 else if (left_is_pressed && val >= 0x6a)
488 analog->analogbits[0] |= ~0xBF;//release left
489
490
491 if (val >= 0xab)
492 analog->analogbits[0] &= 0x7F;//press right
493 else if (right_is_pressed && val <= 0x95)
494 analog->analogbits[0] |= ~0x7F;//release right
495 }
496 }
497
498 //////////////////////////////////////////////////////////////////////////////
499
PerAxis2Value(PerAnalog_struct * analog,u32 val)500 void PerAxis2Value(PerAnalog_struct * analog, u32 val)
501 {
502 analog->analogbits[3] = (u8)val;
503
504 if (analog->perid == PERMISSIONSTICK ||
505 analog->perid == PERTWINSTICKS)
506 {
507 int up_is_pressed = (analog->analogbits[0] & (1 << 4)) == 0;
508 int down_is_pressed = (analog->analogbits[0] & (1 << 5)) == 0;
509
510 if (val <= 0x65)
511 analog->analogbits[0] &= 0xEF;//press up
512 else if (up_is_pressed && val >= 0x6a)
513 analog->analogbits[0] |= ~0xEF;//release up
514
515
516 if (val >= 0xa9)
517 analog->analogbits[0] &= 0xDF;//press down
518 else if (down_is_pressed && val <= 0x94)
519 analog->analogbits[0] |= ~0xDF;//release down
520 }
521 }
522
523 //////////////////////////////////////////////////////////////////////////////
524
PerAxis3Value(PerAnalog_struct * analog,u32 val)525 void PerAxis3Value(PerAnalog_struct * analog, u32 val)
526 {
527 if (analog->perid != PERMISSIONSTICK)
528 analog->analogbits[4] = (u8)val;
529 else
530 analog->analogbits[4] = (u8)(-(s8)val);//axis inverted on mission stick
531 }
532
533 //////////////////////////////////////////////////////////////////////////////
534
PerAxis4Value(PerAnalog_struct * analog,u32 val)535 void PerAxis4Value(PerAnalog_struct * analog, u32 val)
536 {
537 analog->analogbits[5] = (u8)val;
538 }
539
540 //////////////////////////////////////////////////////////////////////////////
541
542 //left stick L/R
PerAxis5Value(PerAnalog_struct * analog,u32 val)543 void PerAxis5Value(PerAnalog_struct * analog, u32 val)
544 {
545 analog->analogbits[6] = (u8)val;
546 }
547
548 //////////////////////////////////////////////////////////////////////////////
549
550 //left stick U/D
PerAxis6Value(PerAnalog_struct * analog,u32 val)551 void PerAxis6Value(PerAnalog_struct * analog, u32 val)
552 {
553 analog->analogbits[7] = (u8)val;
554 }
555
556 //////////////////////////////////////////////////////////////////////////////
557
558 //left stick throttle
PerAxis7Value(PerAnalog_struct * analog,u32 val)559 void PerAxis7Value(PerAnalog_struct * analog, u32 val)
560 {
561 if (analog->perid != PERTWINSTICKS)
562 analog->analogbits[8] = (u8)val;
563 else
564 analog->analogbits[8] = (u8)(-(s8)val);//axis inverted on mission stick
565 }
566
567 //////////////////////////////////////////////////////////////////////////////
568
PerGunTriggerPressed(PerGun_struct * gun)569 void PerGunTriggerPressed(PerGun_struct * gun)
570 {
571 *(gun->gunbits) &= 0xEF;
572 }
573
574 //////////////////////////////////////////////////////////////////////////////
575
PerGunTriggerReleased(PerGun_struct * gun)576 void PerGunTriggerReleased(PerGun_struct * gun)
577 {
578 *(gun->gunbits) |= 0x10;
579 }
580
581 //////////////////////////////////////////////////////////////////////////////
582
PerGunStartPressed(PerGun_struct * gun)583 void PerGunStartPressed(PerGun_struct * gun)
584 {
585 *(gun->gunbits) &= 0xDF;
586 }
587
588 //////////////////////////////////////////////////////////////////////////////
589
PerGunStartReleased(PerGun_struct * gun)590 void PerGunStartReleased(PerGun_struct * gun)
591 {
592 *(gun->gunbits) |= 0x20;
593 }
594
595 //////////////////////////////////////////////////////////////////////////////
596
PerGunMove(PerGun_struct * gun,s32 dispx,s32 dispy)597 void PerGunMove(PerGun_struct * gun, s32 dispx, s32 dispy)
598 {
599 int x, y;
600 x = (*(gun->gunbits+1) << 8) + *(gun->gunbits+2) + (dispx / 4);
601 y = (*(gun->gunbits+3) << 8) + *(gun->gunbits+4) - (dispy / 4);
602
603 if (x < 0)
604 x = 0;
605 else if (x >= 320) // fix me
606 x = 319;
607
608 if (y < 0)
609 y = 0;
610 else if (y >= 224) // fix me
611 y = 223;
612
613 *(gun->gunbits+1) = x >> 8;
614 *(gun->gunbits+2) = x;
615 *(gun->gunbits+3) = y >> 8;
616 *(gun->gunbits+4) = y;
617 }
618
619 //////////////////////////////////////////////////////////////////////////////
620
PerAddPeripheral(PortData_struct * port,int perid)621 void * PerAddPeripheral(PortData_struct *port, int perid)
622 {
623 int pernum = port->data[0] & 0xF;
624 int i;
625 int peroffset=1;
626 u8 size;
627 int current = 1;
628 void * controller;
629
630 if (pernum == 0xF)
631 return NULL;
632 else if (perid == PERGUN && pernum == 1) // Gun doesn't work with multi-tap
633 return NULL;
634
635 // if only one peripheral is connected use 0xF0(unless Gun), otherwise use 0x00 or 0x10
636 if (pernum == 0)
637 {
638 pernum = 1;
639
640 if (perid != PERGUN)
641 port->data[0] = 0xF1;
642 else
643 port->data[0] = 0xA0;
644 }
645 else
646 {
647 if (pernum == 1)
648 {
649 u8 tmp = peroffset;
650 tmp += (port->data[peroffset] & 0xF) + 1;
651
652 for(i = 0;i < 5;i++)
653 port->data[tmp + i] = 0xFF;
654 }
655 pernum = 6;
656 port->data[0] = 0x16;
657
658 // figure out where we're at, then add peripheral id + 1
659 current = 0;
660 size = port->data[peroffset] & 0xF;
661 while ((current < pernum) && (size != 0xF))
662 {
663 peroffset += size + 1;
664 current++;
665 size = port->data[peroffset] & 0xF;
666 }
667
668 if (current == pernum)
669 {
670 return NULL;
671 }
672 current++;
673 }
674
675 port->data[peroffset] = perid;
676 peroffset++;
677
678 // set peripheral data for peripheral to default values and adjust size
679 // of port data
680 switch (perid)
681 {
682 case PERPAD:
683 port->data[peroffset] = 0xFF;
684 port->data[peroffset+1] = 0xFF;
685 port->size = peroffset+(perid&0xF);
686 break;
687 case PERWHEEL:
688 port->data[peroffset] = 0xFF;
689 port->data[peroffset+1] = 0xFF;
690 port->data[peroffset+2] = 0x7F;
691 port->size = peroffset+(perid&0xF);
692 break;
693 case PERMISSIONSTICK:
694 port->data[peroffset] = 0xFF;
695 port->data[peroffset + 1] = 0xFF;
696 port->data[peroffset + 2] = 0x7F;
697 port->data[peroffset + 3] = 0x7F;
698 port->data[peroffset + 4] = 0x7F;
699 port->size = peroffset + (perid & 0xF);
700 break;
701 case PERTWINSTICKS://also double mission sticks
702 port->data[peroffset] = 0xFF;
703 port->data[peroffset + 1] = 0xFF;
704 //right stick
705 port->data[peroffset + 2] = 0x7F;
706 port->data[peroffset + 3] = 0x7F;
707 port->data[peroffset + 4] = 0x7F;
708 //left stick
709 port->data[peroffset + 5] = 0x7F;
710 port->data[peroffset + 6] = 0x7F;
711 port->data[peroffset + 7] = 0x7F;
712 port->size = peroffset + (perid & 0xF);
713 break;
714 case PER3DPAD:
715 port->data[peroffset] = 0xFF;
716 port->data[peroffset+1] = 0xFF;
717 port->data[peroffset+2] = 0x7F;
718 port->data[peroffset+3] = 0x7F;
719 port->data[peroffset+4] = 0x7F;
720 port->data[peroffset+5] = 0x7F;
721 port->size = peroffset+(perid&0xF);
722 break;
723 case PERGUN:
724 port->data[peroffset] = 0x7C;
725 port->data[peroffset + 1] = 0xFF;
726 port->data[peroffset + 2] = 0xFF;
727 port->data[peroffset + 3] = 0xFF;
728 port->data[peroffset + 4] = 0xFF;
729 port->size = 1;
730 break;
731 case PERKEYBOARD:
732 port->data[peroffset] = 0xFF;
733 port->data[peroffset+1] = 0xF8;
734 port->data[peroffset+2] = 0x06;
735 port->data[peroffset+3] = 0x00;
736 port->size = peroffset+(perid&0xF);
737 break;
738 case PERMOUSE:
739 port->data[peroffset] = 0;
740 port->data[peroffset + 1] = 0;
741 port->data[peroffset + 2] = 0;
742 port->size = peroffset+(perid&0xF);
743 break;
744 default: break;
745 }
746
747 if (perid != PERGUN)
748 {
749 u8 tmp = peroffset;
750 tmp += (perid & 0xF);
751 for(i = 0;i < (pernum - current);i++)
752 {
753 port->data[tmp + i] = 0xFF;
754 port->size++;
755 }
756 }
757
758 controller = (port->data + (peroffset - 1));
759 switch (perid)
760 {
761 case PERPAD:
762 PerUpdateConfig(perpadbaseconfig, sizeof(perpadbaseconfig)/sizeof(PerBaseConfig_struct), controller);
763 break;
764 case PERWHEEL:
765 case PERMISSIONSTICK:
766 case PER3DPAD:
767 case PERTWINSTICKS:
768 PerUpdateConfig(perpadbaseconfig, sizeof(perpadbaseconfig)/sizeof(PerBaseConfig_struct), controller);
769 PerUpdateConfig(peranalogbaseconfig, sizeof(peranalogbaseconfig)/sizeof(PerBaseConfig_struct), controller);
770 break;
771 case PERGUN:
772 PerUpdateConfig(pergunbaseconfig, sizeof(pergunbaseconfig)/sizeof(PerBaseConfig_struct), controller);
773 break;
774 case PERMOUSE:
775 PerUpdateConfig(permousebaseconfig, sizeof(permousebaseconfig)/sizeof(PerBaseConfig_struct), controller);
776 break;
777 }
778 return controller;
779 }
780
781 //////////////////////////////////////////////////////////////////////////////
782
PerGetId(void * peripheral)783 int PerGetId(void * peripheral)
784 {
785 u8 * id = peripheral;
786 return *id;
787 }
788
789 //////////////////////////////////////////////////////////////////////////////
790
PerFlush(PortData_struct * port)791 void PerFlush(PortData_struct * port)
792 {
793 /* FIXME this function only flush data if there's a mouse connected as
794 * first peripheral */
795 u8 perid = port->data[1];
796 if (perid == 0xE3)
797 {
798 PerMouse_struct * mouse = (PerMouse_struct *) (port->data + 1);
799
800 mouse->mousebits[0] &= 0x0F;
801 mouse->mousebits[1] = 0;
802 mouse->mousebits[2] = 0;
803 }
804 }
805
806 //////////////////////////////////////////////////////////////////////////////
807
PerKeyDown(u32 key)808 void PerKeyDown(u32 key)
809 {
810 unsigned int i = 0;
811
812 while(i < perkeyconfigsize)
813 {
814 if (key == perkeyconfig[i].key)
815 {
816 if(perkeyconfig[i].base->Press)
817 perkeyconfig[i].base->Press(perkeyconfig[i].controller);
818 }
819 i++;
820 }
821 }
822
823 //////////////////////////////////////////////////////////////////////////////
824
PerKeyUp(u32 key)825 void PerKeyUp(u32 key)
826 {
827 unsigned int i = 0;
828
829 while(i < perkeyconfigsize)
830 {
831 if (key == perkeyconfig[i].key)
832 {
833 if(perkeyconfig[i].base->Release)
834 perkeyconfig[i].base->Release(perkeyconfig[i].controller);
835 }
836 i++;
837 }
838 }
839
840 //////////////////////////////////////////////////////////////////////////////
841
PerSetKey(u32 key,u8 name,void * controller)842 void PerSetKey(u32 key, u8 name, void * controller)
843 {
844 unsigned int i = 0;
845
846 while(i < perkeyconfigsize)
847 {
848 if ((name == perkeyconfig[i].base->name) && (controller == perkeyconfig[i].controller))
849 {
850 perkeyconfig[i].key = key;
851 }
852 i++;
853 }
854 }
855
856 //////////////////////////////////////////////////////////////////////////////
857
PerAxisValue(u32 key,u8 val)858 void PerAxisValue(u32 key, u8 val)
859 {
860 unsigned int i = 0;
861
862 while(i < perkeyconfigsize)
863 {
864 if (key == perkeyconfig[i].key)
865 {
866 if (perkeyconfig[i].base->SetAxisValue)
867 perkeyconfig[i].base->SetAxisValue(perkeyconfig[i].controller, val);
868 }
869 i++;
870 }
871 }
872
873 //////////////////////////////////////////////////////////////////////////////
874
PerAxisMove(u32 key,s32 dispx,s32 dispy)875 void PerAxisMove(u32 key, s32 dispx, s32 dispy)
876 {
877 unsigned int i = 0;
878
879 while(i < perkeyconfigsize)
880 {
881 if (key == perkeyconfig[i].key)
882 {
883 if (perkeyconfig[i].base->MoveAxis)
884 perkeyconfig[i].base->MoveAxis(perkeyconfig[i].controller, dispx, dispy);
885 }
886 i++;
887 }
888 }
889
890 //////////////////////////////////////////////////////////////////////////////
891
PerPortReset(void)892 void PerPortReset(void)
893 {
894 PORTDATA1.data[0] = 0xF0;
895 PORTDATA1.size = 1;
896 PORTDATA2.data[0] = 0xF0;
897 PORTDATA2.size = 1;
898
899 perkeyconfigsize = 0;
900 if (perkeyconfig)
901 free(perkeyconfig);
902 perkeyconfig = NULL;
903 }
904
905 //////////////////////////////////////////////////////////////////////////////
906
PerUpdateConfig(PerBaseConfig_struct * baseconfig,int nelems,void * controller)907 void PerUpdateConfig(PerBaseConfig_struct * baseconfig, int nelems, void * controller)
908 {
909 u32 oldsize = perkeyconfigsize;
910 u32 i, j;
911
912 perkeyconfigsize += nelems;
913 perkeyconfig = realloc(perkeyconfig, perkeyconfigsize * sizeof(PerConfig_struct));
914 j = 0;
915 for(i = oldsize;i < perkeyconfigsize;i++)
916 {
917 perkeyconfig[i].base = baseconfig + j;
918 perkeyconfig[i].controller = controller;
919 j++;
920 }
921 }
922
923 //////////////////////////////////////////////////////////////////////////////
924
PerPadAdd(PortData_struct * port)925 PerPad_struct * PerPadAdd(PortData_struct * port)
926 {
927 return PerAddPeripheral(port, PERPAD);
928 }
929
930 //////////////////////////////////////////////////////////////////////////////
931
PerMouseAdd(PortData_struct * port)932 PerMouse_struct * PerMouseAdd(PortData_struct * port)
933 {
934 return PerAddPeripheral(port, PERMOUSE);
935 }
936
937 //////////////////////////////////////////////////////////////////////////////
938
PerWheelAdd(PortData_struct * port)939 PerAnalog_struct * PerWheelAdd(PortData_struct * port)
940 {
941 return PerAddPeripheral(port, PERWHEEL);
942 }
943
944 //////////////////////////////////////////////////////////////////////////////
945
PerMissionStickAdd(PortData_struct * port)946 PerAnalog_struct * PerMissionStickAdd(PortData_struct * port)
947 {
948 return PerAddPeripheral(port, PERMISSIONSTICK);
949 }
950
951 //////////////////////////////////////////////////////////////////////////////
952
Per3DPadAdd(PortData_struct * port)953 PerAnalog_struct * Per3DPadAdd(PortData_struct * port)
954 {
955 return PerAddPeripheral(port, PER3DPAD);
956 }
957
958 //////////////////////////////////////////////////////////////////////////////
959
PerTwinSticksAdd(PortData_struct * port)960 PerAnalog_struct * PerTwinSticksAdd(PortData_struct * port)
961 {
962 return PerAddPeripheral(port, PERTWINSTICKS);
963 }
964
965 //////////////////////////////////////////////////////////////////////////////
966
PerGunAdd(PortData_struct * port)967 PerGun_struct * PerGunAdd(PortData_struct * port)
968 {
969 return PerAddPeripheral(port, PERGUN);
970 }
971
972 //////////////////////////////////////////////////////////////////////////////
973 // Dummy Interface
974 //////////////////////////////////////////////////////////////////////////////
975
976 int PERDummyInit(void);
977 void PERDummyDeInit(void);
978 int PERDummyHandleEvents(void);
979
980 u32 PERDummyScan(u32 flags);
981 void PERDummyFlush(void);
982 void PERDummyKeyName(u32 key, char * name, int size);
983
984 PerInterface_struct PERDummy = {
985 PERCORE_DUMMY,
986 "Dummy Input Interface",
987 PERDummyInit,
988 PERDummyDeInit,
989 PERDummyHandleEvents,
990 PERDummyScan,
991 0,
992 PERDummyFlush,
993 PERDummyKeyName
994 };
995
996 //////////////////////////////////////////////////////////////////////////////
997
PERDummyInit(void)998 int PERDummyInit(void) {
999
1000 return 0;
1001 }
1002
1003 //////////////////////////////////////////////////////////////////////////////
1004
PERDummyDeInit(void)1005 void PERDummyDeInit(void) {
1006 }
1007
1008 //////////////////////////////////////////////////////////////////////////////
1009
PERDummyHandleEvents(void)1010 int PERDummyHandleEvents(void) {
1011 if (YabauseExec() != 0)
1012 return -1;
1013
1014 return 0;
1015 }
1016
1017 //////////////////////////////////////////////////////////////////////////////
1018
PERDummyScan(u32 flags)1019 u32 PERDummyScan(u32 flags) {
1020 // Scan and return next action based on flags value
1021 // See PERSF_* in peripheral.h for full list of flags.
1022 // If no specified flags are supported return 0
1023
1024 return 0;
1025 }
1026
1027 //////////////////////////////////////////////////////////////////////////////
1028
PERDummyFlush(void)1029 void PERDummyFlush(void) {
1030 }
1031
1032 //////////////////////////////////////////////////////////////////////////////
1033
PERDummyKeyName(UNUSED u32 key,char * name,UNUSED int size)1034 void PERDummyKeyName(UNUSED u32 key, char * name, UNUSED int size) {
1035 *name = 0;
1036 }
1037