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