1 /*---------------------------------------------------------------------------*
2 
3   Copyright 2010-2012 Nintendo.  All rights reserved.
4 
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law.  They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10 
11  *---------------------------------------------------------------------------*/
12 ////===========================================================================
13 ///  demoPad.c
14 ///
15 ///     This is a pad code for the demo library.
16 ///
17 ////===========================================================================
18 
19 #include <cafe/demo.h>
20 #ifdef _DEBUG
21 #include <stdio.h>
22 #endif
23 
24 // -------------------------------------------------------------------------
25 //  Global Values
26 // -------------------------------------------------------------------------
27 // Demo Pad Status
28 DemoPadStatus  g_DemoPad[ DEMO_PAD_MAX_CONTROLLERS ];
29 
30 // -------------------------------------------------------------------------
31 // Pad Status
32 static PADStatus g_Pad[PAD_MAX_CONTROLLERS]; // internal use only
33 
34 // Pad chanel mask
35 static u32 g_PadChanMask[PAD_MAX_CONTROLLERS] =
36 {
37     PAD_CHAN0_BIT, PAD_CHAN1_BIT, PAD_CHAN2_BIT, PAD_CHAN3_BIT
38 };
39 
40 // ------------------------------------------------------------------------
41 //  Macro definitions
42 // ------------------------------------------------------------------------
43 #define padButtonDown(buttonLast, button)   \
44     ((u16) (((buttonLast) ^ (button)) & (button)))
45 
46 #define padButtonUp(buttonLast, button)     \
47     ((u16) (((buttonLast) ^ (button)) & (buttonLast)))
48 
49 //--------------------------------------------------------------------------
50 //   Forward references
51 //--------------------------------------------------------------------------
52 static void SetPadInfo ( PADStatus* pad, DemoPadStatus* dmpad );
53 
54 // -------------------------------------------------------------------------
55 //  Internal Fuctions
56 // -------------------------------------------------------------------------
57 // Attaches informations such as down/up, stick direction.
SetPadInfo(PADStatus * pad,DemoPadStatus * dmpad)58 static void SetPadInfo ( PADStatus* pad, DemoPadStatus* dmpad )
59 {
60     u16  dirs;
61 
62     if ( pad->err != PAD_ERR_TRANSFER )
63     {
64         // Detects which direction is the stick(s) pointing.
65         // This can be used when we want to use a stick as direction pad.
66         dirs = 0;
67         if ( pad->stickX    < - DEMO_STICK_THRESHOLD )
68             dirs |= DEMO_STICK_LEFT;
69         if ( pad->stickX    >   DEMO_STICK_THRESHOLD )
70             dirs |= DEMO_STICK_RIGHT;
71         if ( pad->stickY    < - DEMO_STICK_THRESHOLD )
72             dirs |= DEMO_STICK_DOWN;
73         if ( pad->stickY    >   DEMO_STICK_THRESHOLD )
74             dirs |= DEMO_STICK_UP;
75         if ( pad->substickX < - DEMO_STICK_THRESHOLD )
76             dirs |= DEMO_SUBSTICK_LEFT;
77         if ( pad->substickX >   DEMO_STICK_THRESHOLD )
78             dirs |= DEMO_SUBSTICK_RIGHT;
79         if ( pad->substickY < - DEMO_STICK_THRESHOLD )
80             dirs |= DEMO_SUBSTICK_DOWN;
81         if ( pad->substickY >   DEMO_STICK_THRESHOLD )
82             dirs |= DEMO_SUBSTICK_UP;
83 
84         // Get the direction newly detected / released
85         dmpad->dirsNew      = padButtonDown(dmpad->dirs, dirs);
86         dmpad->dirsReleased = padButtonUp(dmpad->dirs, dirs);
87         dmpad->dirs         = dirs;
88 
89         // Get DOWN/UP status of all buttons
90         dmpad->buttonDown = padButtonDown(dmpad->button, pad->button);
91         dmpad->buttonUp   = padButtonUp(dmpad->button, pad->button);
92 
93         // Get delta of analogs
94         dmpad->stickDeltaX = (s16)(pad->stickX - dmpad->stickX);
95         dmpad->stickDeltaY = (s16)(pad->stickY - dmpad->stickY);
96         dmpad->substickDeltaX = (s16)(pad->substickX - dmpad->substickX);
97         dmpad->substickDeltaY = (s16)(pad->substickY - dmpad->substickY);
98 
99         dmpad->lastButton = dmpad->button;
100 
101         // Copy current status into DEMOPadStatus field
102         dmpad->button = pad->button;
103         dmpad->stickX = pad->stickX;
104         dmpad->stickY = pad->stickY;
105         dmpad->substickX = pad->substickX;
106         dmpad->substickY = pad->substickY;
107         dmpad->triggerLeft  = pad->triggerLeft;
108         dmpad->triggerRight = pad->triggerRight;
109         dmpad->analogA = pad->analogA;
110         dmpad->analogB = pad->analogB;
111         dmpad->err = pad->err;
112     }
113     else
114     {
115         // Get the direction newly detected / released
116         dmpad->dirsNew = dmpad->dirsReleased = 0;
117 
118         // Get DOWN/UP status of all buttons
119         dmpad->buttonDown = dmpad->buttonUp = 0;
120 
121         // Get delta of analogs
122         dmpad->stickDeltaX =    dmpad->stickDeltaY    = 0;
123         dmpad->substickDeltaX = dmpad->substickDeltaY = 0;
124     }
125 }
126 
127 // -------------------------------------------------------------------------
128 //  Initialize
129 // -------------------------------------------------------------------------
DEMOPadInit()130 void DEMOPadInit()
131 {
132     u32 i;
133 
134     // Pad init
135     PADInit();
136 
137     // Reset exported pad status
138     for (i = 0 ; i < DEMO_PAD_MAX_CONTROLLERS ; i++)
139     {
140         g_DemoPad[i].button = 0;
141         g_DemoPad[i].stickX = 0;
142         g_DemoPad[i].stickY = 0;
143         g_DemoPad[i].substickX = 0;
144         g_DemoPad[i].substickY = 0;
145         g_DemoPad[i].triggerLeft = 0;
146         g_DemoPad[i].triggerRight = 0;
147         g_DemoPad[i].analogA = 0;
148         g_DemoPad[i].analogB = 0;
149         g_DemoPad[i].err = 0;
150         g_DemoPad[i].lastButton = 0;
151         g_DemoPad[i].buttonDown = 0;
152         g_DemoPad[i].buttonUp = 0;
153         g_DemoPad[i].dirs = 0;
154         g_DemoPad[i].dirsNew = 0;
155         g_DemoPad[i].dirsReleased = 0;
156         g_DemoPad[i].stickDeltaX = 0;
157         g_DemoPad[i].stickDeltaY = 0;
158         g_DemoPad[i].substickDeltaX = 0;
159         g_DemoPad[i].substickDeltaY = 0;
160     }
161 }
162 
163 // -------------------------------------------------------------------------
164 //  ShutDown
165 // -------------------------------------------------------------------------
DEMOPadShutdown()166 void DEMOPadShutdown()
167 {
168     u32 i;
169     // Reset exported pad status
170     for (i = 0 ; i < DEMO_PAD_MAX_CONTROLLERS ; i++)
171     {
172         g_DemoPad[i].button = 0;
173         g_DemoPad[i].stickX = 0;
174         g_DemoPad[i].stickY = 0;
175         g_DemoPad[i].substickX = 0;
176         g_DemoPad[i].substickY = 0;
177         g_DemoPad[i].triggerLeft = 0;
178         g_DemoPad[i].triggerRight = 0;
179         g_DemoPad[i].analogA = 0;
180         g_DemoPad[i].analogB = 0;
181         g_DemoPad[i].err = 0;
182         g_DemoPad[i].lastButton = 0;
183         g_DemoPad[i].buttonDown = 0;
184         g_DemoPad[i].buttonUp = 0;
185         g_DemoPad[i].dirs = 0;
186         g_DemoPad[i].dirsNew = 0;
187         g_DemoPad[i].dirsReleased = 0;
188         g_DemoPad[i].stickDeltaX = 0;
189         g_DemoPad[i].stickDeltaY = 0;
190         g_DemoPad[i].substickDeltaX = 0;
191         g_DemoPad[i].substickDeltaY = 0;
192     }
193 }
194 
195 // -------------------------------------------------------------------------
196 //  Read
197 // -------------------------------------------------------------------------
198 
DEMOPadRead()199 u32 DEMOPadRead ()
200 {
201     u32 i;
202 
203     u32 ResetReq = 0; // for error handling
204 
205     // Read current PAD status
206     PADRead( g_Pad );
207     PADClampCircle( g_Pad );
208 
209     for ( i = 0 ; i < DEMO_PAD_MAX_CONTROLLERS ; i++ )
210     {
211         // Connection check
212         if ( g_Pad[i].err == PAD_ERR_NO_CONTROLLER )
213         {
214             ResetReq |= g_PadChanMask[i];
215         }
216 
217         SetPadInfo( &g_Pad[i], &g_DemoPad[i] );
218     }
219 
220     return TRUE;
221 }
222 
223