1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - SPI - demos
3   File:     main.c
4 
5   Copyright 2003-2008 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   $Date:: 2008-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 #include    <nitro.h>
19 #include    "monkey.h"
20 #include    "snd_data.h"
21 
22 
23 /*---------------------------------------------------------------------------*
24     Constant Definitions
25  *---------------------------------------------------------------------------*/
26 #define     KEY_REPEAT_START    25     // Number of frames until key repeat starts
27 #define     KEY_REPEAT_SPAN     10     // Number of frames between key repeats
28 
29 
30 /*---------------------------------------------------------------------------*
31     Structure Definitions
32  *---------------------------------------------------------------------------*/
33 // Key input data
34 typedef struct KeyInformation
35 {
36     u16     cnt;                       // Unprocessed input value
37     u16     trg;                       // Push trigger input
38     u16     up;                        // Release trigger input
39     u16     rep;                       // Press and hold repeat input
40 
41 }
42 KeyInformation;
43 
44 /*---------------------------------------------------------------------------*
45     Internal Function Definitions
46  *---------------------------------------------------------------------------*/
47 static void Init3D(void);
48 static void Draw3D(void);
49 static void DrawLine(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color);
50 static void VBlankIntr(void);
51 static void KeyRead(KeyInformation * pKey);
52 
53 
54 /*---------------------------------------------------------------------------*
55     Internal Variable Definitions
56  *---------------------------------------------------------------------------*/
57 static KeyInformation gKey;
58 static MICAutoParam gMicAutoParam;
59 static u16 gMicData[192];
60 static TPData gTpData[4];
61 
62 
63 /*---------------------------------------------------------------------------*
64   Name:         NitroMain
65 
66   Description:  Initialization and main loop.
67 
68   Arguments:    None.
69 
70   Returns:      None.
71  *---------------------------------------------------------------------------*/
NitroMain(void)72 void NitroMain(void)
73 {
74     // Various types of initialization
75     OS_Init();
76     OS_InitThread();
77     OS_InitTick();
78     OS_InitAlarm();
79     FX_Init();
80     GX_Init();
81     GX_DispOff();
82     GXS_DispOff();
83     GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
84 
85     // Initializes display settings
86     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
87     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
88     (void)GX_DisableBankForLCDC();
89     MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
90     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
91     MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
92     MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
93 
94     // 3D-related initialization
95     Init3D();
96 
97     // Interrupt settings
98     OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
99     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
100     (void)OS_EnableIrq();
101     (void)OS_EnableInterrupts();
102     (void)GX_VBlankIntr(TRUE);
103 
104     // Start thread for device sampling
105     MonkeyInit();
106 
107     // Initialize sound
108     {
109         SND_Init();
110         SND_AssignWaveArc((SNDBankData *)sound_bank_data, 0, (SNDWaveArc *)sound_wave_data);
111         SND_StartSeq(0, sound_seq_data, 0, (SNDBankData *)sound_bank_data);
112     }
113 
114     // LCD display start
115     GX_DispOn();
116     GXS_DispOn();
117 
118     // Debug string output
119     OS_Printf("ARM9: SPI parallel sampling demo \"spiMonkey\" started.\n");
120 
121     // Empty call for getting key input data (strategy for pressing A button in the IPL)
122     KeyRead(&gKey);
123 
124     // Main loop
125     while (TRUE)
126     {
127         // Get key input data
128         KeyRead(&gKey);
129 
130         // Get mic and touch panel input information
131         MonkeyGetNewMicData(192, gMicData);
132         MonkeyGetNewTpData(4, gTpData);
133 
134         // Render
135         Draw3D();
136 
137         // Sound
138         while (SND_RecvCommandReply(SND_COMMAND_NOBLOCK) != NULL)
139         {
140         }
141         (void)SND_FlushCommand(SND_COMMAND_NOBLOCK);
142 
143         // Waiting for the V-Blank
144         OS_WaitVBlankIntr();
145     }
146 }
147 
148 /*---------------------------------------------------------------------------*
149   Name:         Init3D
150 
151   Description:  Initialization for 3D display.
152 
153   Arguments:    None.
154 
155   Returns:      None.
156  *---------------------------------------------------------------------------*/
Init3D(void)157 static void Init3D(void)
158 {
159     G3X_Init();
160     G3X_InitMtxStack();
161     G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
162     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_3D);
163     GX_SetVisiblePlane(GX_PLANEMASK_BG0);
164     G2_SetBG0Priority(0);
165     G3X_SetShading(GX_SHADING_TOON);
166     G3X_AlphaTest(FALSE, 0);
167     G3X_AlphaBlend(TRUE);
168     G3X_AntiAlias(TRUE);
169     G3X_EdgeMarking(FALSE);
170     G3X_SetFog(FALSE, (GXFogBlend)0, (GXFogSlope)0, 0);
171     G3X_SetClearColor(0, 0, 0x7fff, 63, FALSE);
172     G3_ViewPort(0, 0, 255, 191);
173 }
174 
175 /*---------------------------------------------------------------------------*
176   Name:         Draw3D
177 
178   Description:  Displays waveforms in 3D.
179 
180   Arguments:    None.
181 
182   Returns:      None.
183  *---------------------------------------------------------------------------*/
Draw3D(void)184 static void Draw3D(void)
185 {
186     G3X_Reset();
187 
188     G3_MtxMode(GX_MTXMODE_PROJECTION);
189     G3_Identity();
190     G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
191     G3_Identity();
192 
193     G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, 0, 31, 0);
194 
195     {
196         s32     i;
197 
198         // Waveform display of mic data
199         for (i = 0; i < 191; i++)
200         {
201             DrawLine((s16)(gMicData[i] >> 8),
202                      (s16)(i), (s16)(gMicData[i + 1] >> 8), (s16)(i + 1), GX_RGB(31, 31, 0));
203         }
204 
205         // Display Touch Panel contact as '+' mark
206         for (i = 0; i < 4; i++)
207         {
208             if (gTpData[i].touch == TP_TOUCH_ON)
209             {
210                 if (!(gTpData[i].validity & TP_VALIDITY_INVALID_X))
211                 {
212                     // Display the x coordinate with a line
213                     DrawLine((s16)(gTpData[i].x),
214                              (s16)(0),
215                              (s16)(gTpData[i].x),
216                              (s16)(191), GX_RGB(31 - (i * 6), 31 - (i * 6), 31 - (i * 6)));
217                 }
218                 if (!(gTpData[i].validity & TP_VALIDITY_INVALID_Y))
219                 {
220                     // Display the y coordinate with a line
221                     DrawLine((s16)(0),
222                              (s16)(gTpData[i].y),
223                              (s16)(255),
224                              (s16)(gTpData[i].y), GX_RGB(31 - (i * 6), 31 - (i * 6), 31 - (i * 6)));
225                 }
226             }
227         }
228     }
229 
230     G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
231 }
232 
233 /*---------------------------------------------------------------------------*
234   Name:         DrawLine
235 
236   Description:  Renders lines with triangular polygons.
237 
238   Arguments:    sx: X-coordinate of line's starting point
239                 sy: Y-coordinate of line's starting point
240                 ex: X-coordinate of line's ending point
241                 ey: Y-coordinate of line's ending point
242                 color: Color of line drawn
243 
244   Returns:      None.
245  *---------------------------------------------------------------------------*/
DrawLine(s16 sx,s16 sy,s16 ex,s16 ey,GXRgb color)246 static void DrawLine(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color)
247 {
248     fx16    fsx;
249     fx16    fsy;
250     fx16    fex;
251     fx16    fey;
252 
253     fsx = (fx16)(((sx - 128) * 0x1000) / 128);
254     fsy = (fx16)(((96 - sy) * 0x1000) / 96);
255     fex = (fx16)(((ex - 128) * 0x1000) / 128);
256     fey = (fx16)(((96 - ey) * 0x1000) / 96);
257 
258     G3_Begin(GX_BEGIN_TRIANGLES);
259     {
260         G3_Color(color);
261         G3_Vtx(fsx, fsy, 0);
262         G3_Color(color);
263         G3_Vtx(fex, fey, 0);
264         G3_Color(color);
265         G3_Vtx(fsx, fsy, 1);
266     }
267     G3_End();
268 }
269 
270 /*---------------------------------------------------------------------------*
271   Name:         VBlankIntr
272 
273   Description:  V-Blank interrupt vector.
274 
275   Arguments:    None.
276 
277   Returns:      None.
278  *---------------------------------------------------------------------------*/
VBlankIntr(void)279 static void VBlankIntr(void)
280 {
281     // Sets the IRQ check flag
282     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
283 }
284 
285 /*---------------------------------------------------------------------------*
286   Name:         KeyRead
287 
288   Description:  Edits key input data.
289                 Detects press trigger, release trigger, and press-and-hold repeat.
290 
291   Arguments:    pKey: Structure that holds key input data to be edited
292 
293   Returns:      None.
294  *---------------------------------------------------------------------------*/
KeyRead(KeyInformation * pKey)295 static void KeyRead(KeyInformation * pKey)
296 {
297     static u16 repeat_count[12];
298     int     i;
299     u16     r;
300 
301     r = PAD_Read();
302     pKey->trg = 0x0000;
303     pKey->up = 0x0000;
304     pKey->rep = 0x0000;
305 
306     for (i = 0; i < 12; i++)
307     {
308         if (r & (0x0001 << i))
309         {
310             if (!(pKey->cnt & (0x0001 << i)))
311             {
312                 pKey->trg |= (0x0001 << i);     // Press trigger
313                 repeat_count[i] = 1;
314             }
315             else
316             {
317                 if (repeat_count[i] > KEY_REPEAT_START)
318                 {
319                     pKey->rep |= (0x0001 << i); // Press-and-hold repeat
320                     repeat_count[i] = KEY_REPEAT_START - KEY_REPEAT_SPAN;
321                 }
322                 else
323                 {
324                     repeat_count[i]++;
325                 }
326             }
327         }
328         else
329         {
330             if (pKey->cnt & (0x0001 << i))
331             {
332                 pKey->up |= (0x0001 << i);      // Release trigger
333             }
334         }
335     }
336     pKey->cnt = r;                     // Unprocessed key input
337 }
338 
339 /*---------------------------------------------------------------------------*
340   End of file
341  *---------------------------------------------------------------------------*/
342