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