1 /*---------------------------------------------------------------------------*
2   Project:  DPL2 Demo application
3   File:     dpl2demo.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: dpl2demo.c,v $
14   Revision 1.12  2006/11/21 08:21:38  aka
15   Removed the zero buffer.
16 
17   Revision 1.11  2006/10/23 02:05:52  aka
18   Changed from AXInit() to AXInitSpecifyMem().
19   Changed from MIXInit() to MIXInitSpecifyMem().
20   Changed from SYNInit() to SYNInitSpecifyMem().
21 
22   Revision 1.10  2006/10/10 08:30:06  aka
23   Revised AXInit(), MIXInit() and SYNInit().
24 
25   Revision 1.9  2006/03/06 09:59:03  kawaset
26   Eliminated warnings.
27 
28   Revision 1.8  2006/02/21 01:04:15  mitu
29   modified am.h path.
30 
31   Revision 1.7  2006/02/20 04:13:07  mitu
32   changed include path from dolphin/ to revolution/.
33 
34   Revision 1.6  2006/02/02 07:26:59  aka
35   Modified using MEM functions instead of OSAlloc()/OSFree().
36 
37   Revision 1.5  2006/02/01 08:07:50  aka
38   Added #ifndef(#ifdef) HOLLYWOOD_REV - #else - #endif.
39 
40   Revision 1.4  2006/01/31 08:07:05  aka
41   Added cast from u32 to u8* in relation to changing API around ARAM.
42 
43   Revision 1.3  2006/01/27 04:54:59  ekwon
44   Corrected "\%" escape sequence warning (replaced with "%%").
45 
46   Revision 1.2  2005/11/08 02:55:02  aka
47   Changed suiting to Revolution's audio spec.
48 
49   Revision 1.1  2005/11/04 05:01:39  aka
50   Imported from dolphin tree.
51 
52     2     4/30/02 4:43p Eugene
53     Fixed pad read contention between UI and application. Requires latest
54     DEMO library!
55 
56     1     1/15/02 3:19p Billyjack
57     created
58 
59   $NoKeywords: $
60  *---------------------------------------------------------------------------*/
61 
62 /*---------------------------------------------------------------------------*
63  * Includes
64  *---------------------------------------------------------------------------*/
65 
66 #include <string.h>
67 #include <demo.h>
68 #include <demo/DEMOWin.h>
69 #include <revolution.h>
70 #include <revolution/mix.h>
71 #include <revolution/sp.h>
72 #include <revolution/mem.h>
73 
74 #include "noise.h"
75 
76 
77 /*---------------------------------------------------------------------------*
78  * SP data
79  *---------------------------------------------------------------------------*/
80 
81 #define SPT_FILE "/axdemo/dpl2/noise.spt"
82 #define SPD_FILE "/axdemo/dpl2/noise.spd"
83 
84 static SPSoundTable *sp_table;
85 static u8           *sp_data;
86 
87 /*---------------------------------------------------------------------------*
88  * Exp Heap
89  *---------------------------------------------------------------------------*/
90 static MEMHeapHandle hExpHeap;
91 
92 /*---------------------------------------------------------------------------*
93  * Application-layer voice abstraction
94  *---------------------------------------------------------------------------*/
95 AXVPB           *voice;
96 SPSoundEntry    *sound;
97 int             panX, panY;
98 
99 /*---------------------------------------------------------------------------*
100  * Prototypes
101  *---------------------------------------------------------------------------*/
102 
103 static void         ax_demo_callback        (void);
104 static void         ax_drop_voice_callback  (void *p);
105 
106 // for UI menus
107 static void         MNU_sound               (DEMOWinMenuInfo *menu, u32 item, u32 *result);
108 static void         MNU_position            (DEMOWinMenuInfo *menu, u32 item, u32 *result);
109 
110 
111 /*---------------------------------------------------------------------------*
112  * UI Stuff
113  *---------------------------------------------------------------------------*/
114 
115 DEMOWinInfo *DebugWin;
116 DEMOWinInfo *PositionWin;
117 
118 DEMOWinMenuItem MenuItem[] =
119 {
120     { "",                       DEMOWIN_ITM_SEPARATOR,  NULL,             NULL },
121     { "Sound: None",            DEMOWIN_ITM_NONE,       MNU_sound,        NULL },
122     { "Position: C Stick",      DEMOWIN_ITM_NONE,       MNU_position,     NULL },
123     { "",                       DEMOWIN_ITM_SEPARATOR,  NULL,             NULL },
124     { "",                       DEMOWIN_ITM_TERMINATOR, NULL,             NULL }
125 };
126 
127 DEMOWinMenuInfo Menu =
128 {
129     "AX DPL2 Demo",             // title
130     NULL,                       // window handle
131     MenuItem,                   // list of menu items
132     5,                          // max num of items to display at a time
133     DEMOWIN_MNU_NONE,           // attribute flags
134 
135     // user callbacks
136     NULL,                       // callback for menu open event
137     NULL,                       // callback for cursor move event
138     NULL,                       // callback for item select event
139     NULL,                       // callback for cancel event
140 
141     // private members
142     0, 0, 0, 0, 0
143 };
144 
145 DEMOWinMenuInfo *MenuPtr;
146 
147 /*===========================================================================*
148  *                   F U N C T I O N    D E F I N I T I O N S
149  *===========================================================================*/
stop_voice(void)150 static void stop_voice(void)
151 {
152     if (voice)
153     {
154         DEMOWinLogPrintf(DebugWin, "Free voice.\n");
155         MIXReleaseChannel(voice);
156         AXFreeVoice(voice);
157         voice = NULL;
158     }
159 }
160 
play_sound(u32 sfx)161 static void play_sound(u32 sfx)
162 {
163     DEMOWinLogPrintf(DebugWin, "Acquire voice.\n");
164     voice = AXAcquireVoice(15, ax_drop_voice_callback, 0);
165 
166     if (voice)
167     {
168         sound = SPGetSoundEntry(sp_table, sfx);
169 
170         SPPrepareSound(sound, voice, sound->sampleRate);
171 
172         MIXInitChannel(voice, 0, 0, -960, -960, -960, panX, 127 - panY, 0);
173         DEMOWinLogPrintf(DebugWin, "Start voice.\n");
174         AXSetVoiceState(voice, AX_PB_STATE_RUN);
175     }
176     else
177     {
178         DEMOWinLogPrintf(DebugWin, "AX Voice allocation failed!\n");
179     }
180 }
181 
182 
183 /*---------------------------------------------------------------------------*
184  *---------------------------------------------------------------------------*/
185 static u32 soundIndex = 0;
MNU_sound(DEMOWinMenuInfo * menu,u32 item,u32 * result)186 static void MNU_sound(DEMOWinMenuInfo *menu, u32 item, u32 *result)
187 {
188 #pragma unused(result)
189 
190     soundIndex++;
191     soundIndex %= 3;
192 
193     switch (soundIndex)
194     {
195     case 0: // None
196 
197         stop_voice();
198         menu->items[item].name = "Sound: None";
199 
200         break;
201 
202     case 1: // White Noise
203 
204         stop_voice();
205         play_sound(SOUND_WHITE_NOISE);
206         menu->items[item].name = "Sound: White Noise";
207 
208         break;
209 
210     case 2: // Pink Noise
211 
212         stop_voice();
213         play_sound(SOUND_PINK_NOISE);
214         menu->items[item].name = "Sound: Pink Noise";
215 
216         break;
217     }
218 
219 }
220 
221 
222 /*---------------------------------------------------------------------------*
223  *---------------------------------------------------------------------------*/
224 static u32 positionIndex = 0;
MNU_position(DEMOWinMenuInfo * menu,u32 item,u32 * result)225 static void MNU_position(DEMOWinMenuInfo *menu, u32 item, u32 *result)
226 {
227 #pragma unused(result)
228 
229     positionIndex++;
230     positionIndex %= 7;
231 
232     switch (positionIndex)
233     {
234     case 0:
235 
236         menu->items[item].name = "Position: C Stick";
237 
238         break;
239 
240     case 1:
241 
242         panX = 0;
243         panY = 0;
244         menu->items[item].name = "Position: L";
245 
246         break;
247 
248     case 2:
249 
250         panX = 63;
251         panY = 0;
252         menu->items[item].name = "Position: C";
253 
254         break;
255 
256     case 3:
257 
258         panX = 127;
259         panY = 0;
260         menu->items[item].name = "Position: R";
261 
262         break;
263 
264     case 4:
265 
266         panX = 0;
267         panY = 127;
268         menu->items[item].name = "Position: Ls";
269 
270         break;
271 
272     case 5:
273 
274         panX = 127;
275         panY = 127;
276         menu->items[item].name = "Position: Rs";
277 
278         break;
279 
280     case 6:
281 
282         panX = 63;
283         panY = 127;
284         menu->items[item].name = "Position: Bs";
285 
286         break;
287 
288     }
289 
290 }
291 
292 
293 /*---------------------------------------------------------------------------*
294  * Name        : position_win_update()
295  * Description : refresh callback for position window
296  * Arguments   :
297  * Returns     :
298  *---------------------------------------------------------------------------*/
position_win_update(DEMOWinInfo * window)299 static void position_win_update(DEMOWinInfo *window)
300 {
301 //    DEMOWinPrintfXY(window, 0, 2, "X: %1.2f Y: %1.2f%%", (f32)(panX + 1) / 128, (f32)(panY + 1) / 128);
302     DEMOWinPrintfXY(window, 0, 2, "X: %1.2f Y: %1.2f%%", (f32)panX / 127, (f32)panY / 127);
303 }
304 
305 /*---------------------------------------------------------------------------*
306  * Name        :
307  * Description :
308  * Arguments   : None.
309  * Returns     : None.
310  *---------------------------------------------------------------------------*/
ax_demo_callback(void)311 static void ax_demo_callback(void)
312 {
313 
314     int substickX;
315     int substickY;
316 
317         substickX = (MenuPtr->handle)->pad.pads[0].substickX;
318         substickY = (MenuPtr->handle)->pad.pads[0].substickY;
319 
320         if (positionIndex == 0)
321         {
322             //DEMOPadRead();
323             //panX = (int)DEMOPadGetSubStickX(0) + 63;
324             //panY = ((int)DEMOPadGetSubStickY(0) - 63) * -1;
325 
326             panX = substickX + 63;
327             panY = (substickY - 63) * -1;
328 
329         }
330 
331         if (voice)
332         {
333             MIXSetPan(voice, panX);
334             MIXSetSPan(voice, 127 - panY);
335             MIXUpdateSettings();
336         }
337 
338 
339 } // end ax_demo_callback()
340 
341 
342 /*---------------------------------------------------------------------------*
343  * Name        : ax_drop_voice_callback()
344  * Description : Invoked by AX when a voice has been forciby dropped.
345  *               Must delete references to the voice from our abstraction layer
346  *               and release the associated MIXer channel.
347  * Arguments   : None.
348  * Returns     : None.
349  *---------------------------------------------------------------------------*/
ax_drop_voice_callback(void * p)350 static void ax_drop_voice_callback(void *p)
351 {
352     if (p == voice)
353     {
354         MIXReleaseChannel(voice);
355         voice = NULL;
356     }
357 } // end ax_demo_callback()
358 
359 
360 /*---------------------------------------------------------------------------*
361  *---------------------------------------------------------------------------*/
LoadFileIntoRam(char * path)362 static void* LoadFileIntoRam(char *path)
363 {
364     DVDFileInfo handle;
365     u32         round_length;
366     s32         read_length;
367     void        *buffer;
368 
369     // Open File
370     if (!DVDOpen(path, &handle))
371     {
372         OSReport("WARNING! Failed to open %s\n", path);
373         return NULL;
374     }
375 
376     // Make sure file length is not 0
377     if (DVDGetLength(&handle) == 0)
378     {
379         OSReport("WARNING! File length is 0\n");
380         return NULL;
381     }
382 
383     round_length = OSRoundUp32B(DVDGetLength(&handle));
384     buffer       = MEMAllocFromExpHeapEx(hExpHeap, round_length,  32);
385 
386     // Make sure we got a buffer
387     if (buffer == NULL)
388     {
389         OSReport("WARNING! Unable to allocate buffer\n");
390         return NULL;
391     }
392 
393     // Read Files
394     read_length = DVDRead(&handle, buffer, (s32)(round_length), 0);
395 
396     // Make sure we read the file correctly
397     if (read_length <= 0)
398     {
399         OSReport("WARNING! File lenght is wrong\n");
400         return NULL;
401     }
402 
403     return buffer;
404 }
405 
406 
407 /*---------------------------------------------------------------------------*
408  * Name        : main()
409  * Description : Hold on to your seatbelts!
410  * Arguments   : None.
411  * Returns     : None.
412  *---------------------------------------------------------------------------*/
main(void)413 void main(void)
414 {
415     void       *arenaMem2Lo;
416     void       *arenaMem2Hi;
417     void       *axBuffer;
418     void       *mixBuffer;
419 
420     // initialize system
421     DEMOInit(NULL);
422     DEMOWinInit();
423 
424     arenaMem2Lo = OSGetMEM2ArenaLo();
425     arenaMem2Hi = OSGetMEM2ArenaHi();
426     hExpHeap    = MEMCreateExpHeap(arenaMem2Lo, (u32)arenaMem2Hi - (u32) arenaMem2Lo);
427 
428     // initialize AI subsystem
429     AIInit(NULL);
430 
431     // initialize AX audio system and MIXer application
432     axBuffer  = MEMAllocFromExpHeapEx(hExpHeap, AXGetMemorySize(AX_MAX_VOICES), 32);
433     mixBuffer = MEMAllocFromExpHeap(hExpHeap, MIXGetMemorySize(AX_MAX_VOICES));
434 
435     AXInitSpecifyMem(AX_MAX_VOICES, axBuffer);
436     MIXInitSpecifyMem(mixBuffer);
437 
438     AXSetMode(AX_MODE_DPL2);
439     MIXSetSoundMode(MIX_SOUND_MODE_DPL2);
440 
441     // -----------------------------------------------------------
442     // Load SP data!
443     // -----------------------------------------------------------
444 
445     // Load sound table
446     sp_table = LoadFileIntoRam(SPT_FILE);
447 
448     // Load sound effects
449     sp_data  = LoadFileIntoRam(SPD_FILE);
450 
451     // -----------------------------------------------------------
452     // initialize sound table!
453     // -----------------------------------------------------------
454     SPInitSoundTable(sp_table, sp_data, NULL);
455 
456     // -----------------------------------------------------------
457     // Initialize demo voice abstraction layer
458     // -----------------------------------------------------------
459     AXRegisterCallback(ax_demo_callback);
460 
461     // -----------------------------------------------------------
462     // Invoke menu system!
463     // -----------------------------------------------------------
464     MenuPtr     = DEMOWinCreateMenuWindow(
465                         &Menu,
466                         20,
467                         100
468                         );
469 
470     DebugWin    = DEMOWinCreateWindow(
471                         (u16)(MenuPtr->handle->x2+10),
472                         20,
473                         620,
474                         440,
475                         "Debug",
476                         1024,
477                         NULL
478                         );
479 
480     PositionWin = DEMOWinCreateWindow(
481                         (u16)(MenuPtr->handle->x1),
482                         (u16)(MenuPtr->handle->y2+10),
483                         (u16)(MenuPtr->handle->x2),
484                         (u16)(MenuPtr->handle->y2+60),
485                         "Position",
486                         0,
487                         position_win_update
488                         );
489 
490     DEMOWinOpenWindow(DebugWin);
491     DEMOWinOpenWindow(PositionWin);
492 
493     DEMOWinLogPrintf(DebugWin, "-------------------------------\n");
494     DEMOWinLogPrintf(DebugWin, "AX DPL2 Demo!\n");
495     DEMOWinLogPrintf(DebugWin, "-------------------------------\n");
496 
497     while (1)
498     {
499 
500         DEMOWinMenu(MenuPtr);
501 
502     }
503 
504 
505 } // end main()
506 
507