/*---------------------------------------------------------------------------* Project: DPL2 Demo application File: dpl2demo.c Copyright (C)1998-2006 Nintendo All Rights Reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Log: dpl2demo.c,v $ Revision 1.12 2006/11/21 08:21:38 aka Removed the zero buffer. Revision 1.11 2006/10/23 02:05:52 aka Changed from AXInit() to AXInitSpecifyMem(). Changed from MIXInit() to MIXInitSpecifyMem(). Changed from SYNInit() to SYNInitSpecifyMem(). Revision 1.10 2006/10/10 08:30:06 aka Revised AXInit(), MIXInit() and SYNInit(). Revision 1.9 2006/03/06 09:59:03 kawaset Eliminated warnings. Revision 1.8 2006/02/21 01:04:15 mitu modified am.h path. Revision 1.7 2006/02/20 04:13:07 mitu changed include path from dolphin/ to revolution/. Revision 1.6 2006/02/02 07:26:59 aka Modified using MEM functions instead of OSAlloc()/OSFree(). Revision 1.5 2006/02/01 08:07:50 aka Added #ifndef(#ifdef) HOLLYWOOD_REV - #else - #endif. Revision 1.4 2006/01/31 08:07:05 aka Added cast from u32 to u8* in relation to changing API around ARAM. Revision 1.3 2006/01/27 04:54:59 ekwon Corrected "\%" escape sequence warning (replaced with "%%"). Revision 1.2 2005/11/08 02:55:02 aka Changed suiting to Revolution's audio spec. Revision 1.1 2005/11/04 05:01:39 aka Imported from dolphin tree. 2 4/30/02 4:43p Eugene Fixed pad read contention between UI and application. Requires latest DEMO library! 1 1/15/02 3:19p Billyjack created $NoKeywords: $ *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* * Includes *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include "noise.h" /*---------------------------------------------------------------------------* * SP data *---------------------------------------------------------------------------*/ #define SPT_FILE "/axdemo/dpl2/noise.spt" #define SPD_FILE "/axdemo/dpl2/noise.spd" static SPSoundTable *sp_table; static u8 *sp_data; /*---------------------------------------------------------------------------* * Exp Heap *---------------------------------------------------------------------------*/ static MEMHeapHandle hExpHeap; /*---------------------------------------------------------------------------* * Application-layer voice abstraction *---------------------------------------------------------------------------*/ AXVPB *voice; SPSoundEntry *sound; int panX, panY; /*---------------------------------------------------------------------------* * Prototypes *---------------------------------------------------------------------------*/ static void ax_demo_callback (void); static void ax_drop_voice_callback (void *p); // for UI menus static void MNU_sound (DEMOWinMenuInfo *menu, u32 item, u32 *result); static void MNU_position (DEMOWinMenuInfo *menu, u32 item, u32 *result); /*---------------------------------------------------------------------------* * UI Stuff *---------------------------------------------------------------------------*/ DEMOWinInfo *DebugWin; DEMOWinInfo *PositionWin; DEMOWinMenuItem MenuItem[] = { { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL }, { "Sound: None", DEMOWIN_ITM_NONE, MNU_sound, NULL }, { "Position: C Stick", DEMOWIN_ITM_NONE, MNU_position, NULL }, { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL }, { "", DEMOWIN_ITM_TERMINATOR, NULL, NULL } }; DEMOWinMenuInfo Menu = { "AX DPL2 Demo", // title NULL, // window handle MenuItem, // list of menu items 5, // max num of items to display at a time DEMOWIN_MNU_NONE, // attribute flags // user callbacks NULL, // callback for menu open event NULL, // callback for cursor move event NULL, // callback for item select event NULL, // callback for cancel event // private members 0, 0, 0, 0, 0 }; DEMOWinMenuInfo *MenuPtr; /*===========================================================================* * F U N C T I O N D E F I N I T I O N S *===========================================================================*/ static void stop_voice(void) { if (voice) { DEMOWinLogPrintf(DebugWin, "Free voice.\n"); MIXReleaseChannel(voice); AXFreeVoice(voice); voice = NULL; } } static void play_sound(u32 sfx) { DEMOWinLogPrintf(DebugWin, "Acquire voice.\n"); voice = AXAcquireVoice(15, ax_drop_voice_callback, 0); if (voice) { sound = SPGetSoundEntry(sp_table, sfx); SPPrepareSound(sound, voice, sound->sampleRate); MIXInitChannel(voice, 0, 0, -960, -960, -960, panX, 127 - panY, 0); DEMOWinLogPrintf(DebugWin, "Start voice.\n"); AXSetVoiceState(voice, AX_PB_STATE_RUN); } else { DEMOWinLogPrintf(DebugWin, "AX Voice allocation failed!\n"); } } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static u32 soundIndex = 0; static void MNU_sound(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(result) soundIndex++; soundIndex %= 3; switch (soundIndex) { case 0: // None stop_voice(); menu->items[item].name = "Sound: None"; break; case 1: // White Noise stop_voice(); play_sound(SOUND_WHITE_NOISE); menu->items[item].name = "Sound: White Noise"; break; case 2: // Pink Noise stop_voice(); play_sound(SOUND_PINK_NOISE); menu->items[item].name = "Sound: Pink Noise"; break; } } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static u32 positionIndex = 0; static void MNU_position(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(result) positionIndex++; positionIndex %= 7; switch (positionIndex) { case 0: menu->items[item].name = "Position: C Stick"; break; case 1: panX = 0; panY = 0; menu->items[item].name = "Position: L"; break; case 2: panX = 63; panY = 0; menu->items[item].name = "Position: C"; break; case 3: panX = 127; panY = 0; menu->items[item].name = "Position: R"; break; case 4: panX = 0; panY = 127; menu->items[item].name = "Position: Ls"; break; case 5: panX = 127; panY = 127; menu->items[item].name = "Position: Rs"; break; case 6: panX = 63; panY = 127; menu->items[item].name = "Position: Bs"; break; } } /*---------------------------------------------------------------------------* * Name : position_win_update() * Description : refresh callback for position window * Arguments : * Returns : *---------------------------------------------------------------------------*/ static void position_win_update(DEMOWinInfo *window) { // DEMOWinPrintfXY(window, 0, 2, "X: %1.2f Y: %1.2f%%", (f32)(panX + 1) / 128, (f32)(panY + 1) / 128); DEMOWinPrintfXY(window, 0, 2, "X: %1.2f Y: %1.2f%%", (f32)panX / 127, (f32)panY / 127); } /*---------------------------------------------------------------------------* * Name : * Description : * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ static void ax_demo_callback(void) { int substickX; int substickY; substickX = (MenuPtr->handle)->pad.pads[0].substickX; substickY = (MenuPtr->handle)->pad.pads[0].substickY; if (positionIndex == 0) { //DEMOPadRead(); //panX = (int)DEMOPadGetSubStickX(0) + 63; //panY = ((int)DEMOPadGetSubStickY(0) - 63) * -1; panX = substickX + 63; panY = (substickY - 63) * -1; } if (voice) { MIXSetPan(voice, panX); MIXSetSPan(voice, 127 - panY); MIXUpdateSettings(); } } // end ax_demo_callback() /*---------------------------------------------------------------------------* * Name : ax_drop_voice_callback() * Description : Invoked by AX when a voice has been forciby dropped. * Must delete references to the voice from our abstraction layer * and release the associated MIXer channel. * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ static void ax_drop_voice_callback(void *p) { if (p == voice) { MIXReleaseChannel(voice); voice = NULL; } } // end ax_demo_callback() /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void* LoadFileIntoRam(char *path) { DVDFileInfo handle; u32 round_length; s32 read_length; void *buffer; // Open File if (!DVDOpen(path, &handle)) { OSReport("WARNING! Failed to open %s\n", path); return NULL; } // Make sure file length is not 0 if (DVDGetLength(&handle) == 0) { OSReport("WARNING! File length is 0\n"); return NULL; } round_length = OSRoundUp32B(DVDGetLength(&handle)); buffer = MEMAllocFromExpHeapEx(hExpHeap, round_length, 32); // Make sure we got a buffer if (buffer == NULL) { OSReport("WARNING! Unable to allocate buffer\n"); return NULL; } // Read Files read_length = DVDRead(&handle, buffer, (s32)(round_length), 0); // Make sure we read the file correctly if (read_length <= 0) { OSReport("WARNING! File lenght is wrong\n"); return NULL; } return buffer; } /*---------------------------------------------------------------------------* * Name : main() * Description : Hold on to your seatbelts! * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ void main(void) { void *arenaMem2Lo; void *arenaMem2Hi; void *axBuffer; void *mixBuffer; // initialize system DEMOInit(NULL); DEMOWinInit(); arenaMem2Lo = OSGetMEM2ArenaLo(); arenaMem2Hi = OSGetMEM2ArenaHi(); hExpHeap = MEMCreateExpHeap(arenaMem2Lo, (u32)arenaMem2Hi - (u32) arenaMem2Lo); // initialize AI subsystem AIInit(NULL); // initialize AX audio system and MIXer application axBuffer = MEMAllocFromExpHeapEx(hExpHeap, AXGetMemorySize(AX_MAX_VOICES), 32); mixBuffer = MEMAllocFromExpHeap(hExpHeap, MIXGetMemorySize(AX_MAX_VOICES)); AXInitSpecifyMem(AX_MAX_VOICES, axBuffer); MIXInitSpecifyMem(mixBuffer); AXSetMode(AX_MODE_DPL2); MIXSetSoundMode(MIX_SOUND_MODE_DPL2); // ----------------------------------------------------------- // Load SP data! // ----------------------------------------------------------- // Load sound table sp_table = LoadFileIntoRam(SPT_FILE); // Load sound effects sp_data = LoadFileIntoRam(SPD_FILE); // ----------------------------------------------------------- // initialize sound table! // ----------------------------------------------------------- SPInitSoundTable(sp_table, sp_data, NULL); // ----------------------------------------------------------- // Initialize demo voice abstraction layer // ----------------------------------------------------------- AXRegisterCallback(ax_demo_callback); // ----------------------------------------------------------- // Invoke menu system! // ----------------------------------------------------------- MenuPtr = DEMOWinCreateMenuWindow( &Menu, 20, 100 ); DebugWin = DEMOWinCreateWindow( (u16)(MenuPtr->handle->x2+10), 20, 620, 440, "Debug", 1024, NULL ); PositionWin = DEMOWinCreateWindow( (u16)(MenuPtr->handle->x1), (u16)(MenuPtr->handle->y2+10), (u16)(MenuPtr->handle->x2), (u16)(MenuPtr->handle->y2+60), "Position", 0, position_win_update ); DEMOWinOpenWindow(DebugWin); DEMOWinOpenWindow(PositionWin); DEMOWinLogPrintf(DebugWin, "-------------------------------\n"); DEMOWinLogPrintf(DebugWin, "AX DPL2 Demo!\n"); DEMOWinLogPrintf(DebugWin, "-------------------------------\n"); while (1) { DEMOWinMenu(MenuPtr); } } // end main()