1 /*---------------------------------------------------------------------------*
2 Project: Sampling callback demo
3 File: sampling.c
4
5 Copyright (C) 1998-2006 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: sampling.c,v $
14 Revision 1.1 02/02/2006 06:11:49 yasuh-to
15 Initial import
16
17
18 5 11/27/01 11:56 Shiki
19 Revised using SISetSamplingRate().
20
21 4 11/21/01 14:32 Shiki
22 Revised.
23
24 3 9/08/01 14:59 Shiki
25 Clean up.
26
27 2 9/07/01 22:00 Shiki
28 Fixed to make this program work even if no controller is attached
29 initially.
30
31 1 9/03/01 19:40:00 Shiki
32 Initial check-in.
33 $NoKeywords: $
34 *---------------------------------------------------------------------------*/
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include <demo.h>
39
40 volatile PADStatus Pads[SI_MAX_CHAN];
41 vu64 Count;
42
SamplingCallback(void)43 static void SamplingCallback(void)
44 {
45 PADStatus pads[SI_MAX_CHAN];
46 s32 chan;
47
48 PADRead(pads);
49 PADClamp(pads);
50 for (chan = 0; chan < SI_MAX_CHAN; ++chan)
51 {
52 if (pads[chan].err != PAD_ERR_TRANSFER)
53 {
54 memcpy((PADStatus*) &Pads[chan], &pads[chan], sizeof(PADStatus));
55 }
56 }
57
58 ++Count;
59 }
60
main(int argc,char * argv[])61 void main(int argc, char* argv[])
62 {
63 BOOL reset = FALSE; // TRUE if reset is requested
64 BOOL enabled;
65 PADStatus pads[SI_MAX_CHAN];
66 s32 chan;
67 u32 chanBit;
68 u32 resetBits;
69 u32 msec;
70 GXRenderModeObj* rmp;
71 GXColor blue = { 0, 0, 127, 0 };
72 s16 x, y;
73
74 DEMOInit(NULL); // for VIInit() and PADInit()
75
76 for (chan = 0; chan < SI_MAX_CHAN; ++chan)
77 {
78 Pads[chan].err = PAD_ERR_NO_CONTROLLER;
79 }
80 PADInit();
81 PADSetSamplingCallback(SamplingCallback);
82
83 msec = 0;
84 if (argc == 2)
85 {
86 msec = (u32) atoi(argv[1]);
87 if (11 < msec)
88 {
89 msec = 0;
90 }
91 }
92 SISetSamplingRate(msec);
93
94 // Clear EFB
95 GXSetCopyClear(blue, 0x00ffffff);
96 GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
97
98 for (;;)
99 {
100 DEMOBeforeRender();
101
102 x = 25;
103 y = 30;
104
105 rmp = DEMOGetRenderModeObj();
106 DEMOInitCaption(DM_FT_XLU, (s16) rmp->fbWidth * 3 / 4, (s16) rmp->efbHeight * 3 / 4);
107
108 enabled = OSDisableInterrupts();
109 memcpy(pads, (PADStatus*) Pads, sizeof Pads);
110 OSRestoreInterrupts(enabled);
111
112 // The user specified sampling callback function is usually beginning
113 // to be called after the next vertical retrace interrupt. Please make
114 // sure that your program does not call PADReset() more than once before
115 // the sampling callback function is called, or the controller is
116 // removed from the controller port.
117 resetBits = 0;
118 for (chan = 0; chan < SI_MAX_CHAN; ++chan)
119 {
120 chanBit = SI_CHAN_BIT(chan);
121 switch (SIProbe(chan))
122 {
123 case SI_GC_CONTROLLER:
124 case SI_GC_WAVEBIRD:
125 if (pads[chan].err == PAD_ERR_NO_CONTROLLER)
126 {
127 resetBits |= chanBit;
128 // Prevent the 2nd call to PADReset() before SamplingCallback() is called.
129 Pads[chan].err = PAD_ERR_NOT_READY;
130 }
131 break;
132 default:
133 Pads[chan].err = PAD_ERR_NO_CONTROLLER;
134 break;
135 }
136 }
137 if (resetBits)
138 {
139 PADReset(resetBits);
140 }
141
142 DEMOPrintf(x, y += 16, 0, "Port AB XY M ZLR +Pad Left Right Trigger");
143 // 1[-2] AB XY M ZLR <>^v (123, 123) (123, 123) (123, 123)
144 for (chan = 0; chan < SI_MAX_CHAN; chan++)
145 {
146 DEMOPrintf(x, y += 16, 0, "%d[%-2d] %c%c %c%c %c %c%c%c %c%c%c%c (%3d, %3d) (%3d, %3d) (%3d, %3d)",
147 chan,
148 pads[chan].err,
149 (pads[chan].button & PAD_BUTTON_A) ? 'O' : '_',
150 (pads[chan].button & PAD_BUTTON_B) ? 'O' : '_',
151 (pads[chan].button & PAD_BUTTON_X) ? 'O' : '_',
152 (pads[chan].button & PAD_BUTTON_Y) ? 'O' : '_',
153 (pads[chan].button & PAD_BUTTON_MENU) ? 'O' : '_',
154 (pads[chan].button & PAD_TRIGGER_Z) ? 'O' : '_',
155 (pads[chan].button & PAD_TRIGGER_L) ? 'O' : '_',
156 (pads[chan].button & PAD_TRIGGER_R) ? 'O' : '_',
157
158 (pads[chan].button & PAD_BUTTON_LEFT) ? '<' : '_',
159 (pads[chan].button & PAD_BUTTON_RIGHT) ? '>' : '_',
160 (pads[chan].button & PAD_BUTTON_UP) ? '^' : '_',
161 (pads[chan].button & PAD_BUTTON_DOWN) ? 'v' : '_',
162
163 pads[chan].stickX,
164 pads[chan].stickY,
165 pads[chan].substickX,
166 pads[chan].substickY,
167 pads[chan].triggerLeft,
168 pads[chan].triggerRight);
169 }
170 DEMOPrintf(x, y += 16, 0, "Samples: %llu", Count);
171 DEMOPrintf(x, y += 16, 0, "Retrace: %u", VIGetRetraceCount());
172
173 DEMODoneRender();
174
175 // Handle reset button
176 if (OSGetResetButtonState())
177 {
178 reset = TRUE;
179 }
180 else if (reset)
181 {
182 // Restart
183 OSResetSystem(FALSE, 0x01, FALSE);
184 }
185 }
186 }
187