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