From c068f22329d5cc722622a2183bbb22eef2093df7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 24 Aug 2026 11:16:07 +0200 Subject: initial import --- src/parsec/aud_bkgn.cpp | 1189 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1189 insertions(+) create mode 100644 src/parsec/aud_bkgn.cpp (limited to 'src/parsec/aud_bkgn.cpp') diff --git a/src/parsec/aud_bkgn.cpp b/src/parsec/aud_bkgn.cpp new file mode 100644 index 0000000..d0b6fb5 --- /dev/null +++ b/src/parsec/aud_bkgn.cpp @@ -0,0 +1,1189 @@ +/* + * PARSEC - + * + * $Author: uberlinuxguy $ - $Date: 2004/09/26 03:43:33 $ + * + * Orginally written by: + * Copyright (c) Clemens Beer 1999 + + Updated by: + Copyright (c) 2003 Sivaram Velauthapillai (sivaram33@hotmail.com or koalabear33@yahoo.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* +UPDATES: +August 10, 2003 + + MP3 support dropped; instead of loading mp3 files, game now loads ogg files +*/ + +// C library +#include +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" + +// global externals +#include "globals.h" + +// subsystem headers +#include "aud_defs.h" + +// local module header +#include "aud_bkgn.h" + +// proprietary module headers +#include "aud_game.h" +#include "aud_supp.h" +#include "con_arg.h" +#include "con_aux.h" +#include "con_com.h" +#include "con_int.h" +#include "con_main.h" +#include "e_callbk.h" +#include "e_events.h" +#include "g_supp.h" +#include "snd_api.h" +#include "sys_file.h" + + +#define NUM_AUDIO_CD_TRACKS 9 +#define NUM_GAMESFX_STREAMS 9 + + +// defined background item types ---------------------------------------------- +// +#define BKGN_ITEM_TYPE_SAMPLE 0x0001 +#define BKGN_ITEM_TYPE_CDTRACK 0x0002 +#define BKGN_ITEM_TYPE_STREAM 0x0004 +#define BKGN_ITEM_TYPE_SILENCE 0x0008 + + +// generic background item structure ------------------------------------------ +// +struct BKGN_Item_s { + BKGN_Item_s* next; + dword type; // type of background item + dword id; // id (sampleid, cdtrack, ...) of background item + char* filename; // filename if item is an audiostream + int groupnext; // don't shuffle after completing this item + int fadein_start; // seconds to start the fadein + int fadein_end; // seconds to end the fadein (full volume) + int fadeout_start; // seconds to start the fadeout + int fadeout_end; // seconds to end the fadeout + int _mksiz32; +}; + + +// module local globals ------------------------------------------------------- +// +static BKGN_Item_s* BKGN_items; +static BKGN_Item_s* BKGN_items_head; +static int BKGN_nVoice; +static int BKGN_nNumItems; +static int BKGN_nCurrentItem; +static int BKGN_Started; +static int BKGN_shuffle = TRUE; + + + + +// console texts -------------------------------------------------------------- +// +static char invalid_command[] = "invalid command."; +static char invalid_sample_specified[] = "invalid sample specified."; +static char invalid_stream_specified[] = "invalid stream specified."; +static char invalid_parameter[] = "invalid parameter."; + + +// paste string area ---------------------------------------------------------- +// +#define PASTE_STR_LEN 255 +static char paste_str[ PASTE_STR_LEN + 1 ]; + + +// get an item specified by an index ------------------------------------------ +// +BKGN_Item_s* BKGN_GetItem( int nItem ) +{ + int nIndex = 0; + for ( BKGN_Item_s* scan = BKGN_items_head; scan != NULL; nIndex++ ) { + BKGN_Item_s* next = scan->next; + + if ( nItem == nIndex ) { + return scan; + } + + scan = next; + } + + return NULL; +} + +// Initializes background music files +//RAM replaced mp3 with ogg vorbis files +void AUD_BackGroundPlayer_Init( int voice ) +{ + BKGN_nVoice = voice; + BKGN_nNumItems = 0; + BKGN_nCurrentItem = -1; + BKGN_Started = FALSE; + BKGN_items = NULL; + BKGN_items_head = NULL; + + if ( !AUX_DISABLE_BACKGROUNDPLAYER_ITEM_FILL ) { + + // add music tracks (either from audio cd or as mp3) + for ( int tid = 2; tid < NUM_AUDIO_CD_TRACKS + 2; tid++ ) { + + sprintf( paste_str, "track%d.ogg", tid ); + AUD_BackGroundPlayer_AddStream( paste_str ); + MSGOUT("Loaded %s", paste_str); + + } + + // add game sfx + for ( int sid = 1; sid < NUM_GAMESFX_STREAMS + 1; sid++ ) { + + sprintf( paste_str, "gamesfx%d.ogg", sid ); + AUD_BackGroundPlayer_AddStream( paste_str ); + MSGOUT("Loaded %s", paste_str); + + } + + // new game sfx in pscdata3.dat + AUD_BackGroundPlayer_AddStream( "gamefx10.ogg" ); + MSGOUT("Loaded gamefx10.ogg" ); + AUD_BackGroundPlayer_AddStream( "gamefx11.ogg" ); + MSGOUT("Loaded gamefx11.ogg" ); + + //????RAM not sure what this silence stuff is ???? + // add some silence + AUD_BackGroundPlayer_AddSilence( 15 ); + AUD_BackGroundPlayer_AddSilence( 15 ); + AUD_BackGroundPlayer_AddSilence( 30 ); + } + +} + + +// kill the background sound player ------------------------------------------- +// +void AUD_BackGroundPlayer_Kill() +{ + for ( BKGN_Item_s* scan = BKGN_items_head; scan != NULL; ) { + BKGN_Item_s* next = scan->next; + FREEMEM( scan ); + scan = next; + } + + BKGN_nNumItems = 0; + BKGN_nCurrentItem = -1; + BKGN_Started = FALSE; + BKGN_items_head = NULL; + BKGN_items = NULL; +} + + +// remove an item from the background list ------------------------------------ +// +PRIVATE +BKGN_Item_s* BKGNm_AddItem( int id, const char *filename, dword type ) +{ + // add the background item to the end of the list + + DBGTXT(MSGOUT("Adding Item with id=%i, filename=%s, type=%d\n", id, filename, type);); + BKGN_Item_s* item = (BKGN_Item_s*) ALLOCMEM( sizeof( BKGN_Item_s ) ); + memset( item, 0, sizeof( BKGN_Item_s ) ); + + item->type = type; + + if ( type == BKGN_ITEM_TYPE_STREAM ) { + + item->id = 0; + item->filename = (char *) ALLOCMEM( strlen( filename ) + 1 ); + strcpy( item->filename, filename ); + + } else { + + item->id = id; + item->filename = NULL; + } + + item->groupnext = FALSE; + item->next = NULL; + + if ( BKGN_items_head == NULL ) { + BKGN_items_head = item; + } + + if ( BKGN_items != NULL ) { + BKGN_items->next = item; + } + + BKGN_items = item; + + // increase the number of attached items + BKGN_nNumItems++; + + return item; +} + + +// remove an item from the background list ------------------------------------ +// +PRIVATE +int BKGNm_RemoveItem( dword id, char *filename, dword type ) +{ + int nNumItems = BKGN_nNumItems; + + BKGN_Item_s* prev = NULL; + for ( BKGN_Item_s* scan = BKGN_items_head; scan != NULL; ) { + BKGN_Item_s* next = scan->next; + + if ( scan->type & type ) { + if ( ( scan->id == id ) && ( scan->filename == filename ) ) { + + if ( prev != NULL ) { + prev->next = next; + } else { + BKGN_items_head = next; + } + + if ( scan->filename != NULL ) + FREEMEM( scan->filename ); + + FREEMEM( scan ); + scan = NULL; + + BKGN_nNumItems--; + } + } + + if ( scan != NULL ) + prev = scan; + + scan = next; + } + + return ( nNumItems != BKGN_nNumItems ); +} + + +// add a sample to be played by the background player ------------------------- +// +int AUD_BackGroundPlayer_AddSample( const char *name ) +{ + if ( name != NULL ) { + // fetch the named sample + int sampleid; + sampleinfo_s* pSampleInfo = AUD_FetchSampleByName( name, &sampleid ); + + if ( pSampleInfo != NULL ) { + BKGN_Item_s* item = BKGNm_AddItem( sampleid, NULL, BKGN_ITEM_TYPE_SAMPLE ); + } + return TRUE; + } + + return FALSE; +} + + +// remove a sample from the list of played items ------------------------------ +// +int AUD_BackGroundPlayer_RemoveSample( char *name ) +{ + if ( name != NULL ) { + + // fetch the named sample + int sampleid; + sampleinfo_s* pSampleInfo = AUD_FetchSampleByName( name, &sampleid ); + + // check the whole list and delete the item if needed + if ( pSampleInfo != NULL ) { + + // stop playing if removed item is the currently played + BKGN_Item_s* curitem = BKGN_GetItem( BKGN_nCurrentItem ); + + if ( ( curitem->id == (dword) sampleid ) && ( curitem->type & BKGN_ITEM_TYPE_SAMPLE ) ) { + AUD_BackGroundPlayer_Stop(); + EVT_RemoveEventType( EVT_TYPE_BKGN_SAMPLE_END ); + EVT_RemoveEventType( EVT_TYPE_BKGN_CDTRACK_END ); + } + + // remove the item + int rc = BKGNm_RemoveItem( sampleid, NULL, BKGN_ITEM_TYPE_SAMPLE ); + + // and start playing again + AUD_BackGroundPlayer_Start( FALSE ); + + return rc; + } + } + + return FALSE; +} + + +// add a cd-track to be played by the background player ----------------------- +// +int AUD_BackGroundPlayer_AddTrack( int track ) +{ + BKGN_Item_s* item = BKGNm_AddItem( track, NULL, BKGN_ITEM_TYPE_CDTRACK ); + + return TRUE; +} + + +// remove a cd-track from the list of played items ---------------------------- +// +int AUD_BackGroundPlayer_RemoveTrack( int track ) +{ + // stop playing if removed item is the currently played + BKGN_Item_s* curitem = BKGN_GetItem( BKGN_nCurrentItem ); + + if ( ( curitem->id == (dword) track ) && ( curitem->type & BKGN_ITEM_TYPE_CDTRACK ) ) { + AUD_BackGroundPlayer_Stop(); + EVT_RemoveEventType( EVT_TYPE_BKGN_SAMPLE_END ); + EVT_RemoveEventType( EVT_TYPE_BKGN_CDTRACK_END ); + } + + // remove the item + int rc = BKGNm_RemoveItem( track, NULL, BKGN_ITEM_TYPE_CDTRACK ); + + // and start playing again + AUD_BackGroundPlayer_Start( FALSE ); + + return rc; +} + + + +// add a sample to be played by the background player ------------------------- +// +int AUD_BackGroundPlayer_AddStream( const char *name ) +{ + if ( name != NULL ) { + + BKGN_Item_s* item = BKGNm_AddItem( 0, name, BKGN_ITEM_TYPE_STREAM ); + + return TRUE; + } + + return FALSE; +} + + +// add a silence delay to the background player list -------------------------- +// +int AUD_BackGroundPlayer_AddSilence( int seconds ) +{ + BKGN_Item_s* item = BKGNm_AddItem( seconds, NULL, BKGN_ITEM_TYPE_SILENCE ); + + return TRUE; +} + + +// remove an item from the list ----------------------------------------------- +// +int AUD_BackGroundPlayer_RemoveItem( int item ) +{ + + // stop playing if removed item is the currently played + if ( BKGN_nCurrentItem == item ) { + AUD_BackGroundPlayer_Stop(); + EVT_RemoveEventType( EVT_TYPE_BKGN_SAMPLE_END ); + EVT_RemoveEventType( EVT_TYPE_BKGN_CDTRACK_END ); + } + + // get the item + BKGN_Item_s* curitem = BKGN_GetItem( item ); + + // remove the item + int rc = BKGNm_RemoveItem( curitem->id, curitem->filename, curitem->type ); + + // and start playing again + AUD_BackGroundPlayer_Start( FALSE ); + + return rc; +} + + +// choose a new item to play in the background -------------------------------- +// +INLINE +int BKGNm_ChooseNewItem() +{ + ASSERT( BKGN_nNumItems > 1 ); + + int nNewSample; + + // get current item + BKGN_Item_s* item = BKGN_GetItem( BKGN_nCurrentItem ); + + int group = item ? item->groupnext : FALSE; + if ( BKGN_shuffle && !group ) { + + nNewSample = ( RAND() % BKGN_nNumItems ); + + while ( nNewSample == BKGN_nCurrentItem ) { + nNewSample = ( RAND() % BKGN_nNumItems ); + } + + } else { + + nNewSample = ( BKGN_nCurrentItem + 1 ) % BKGN_nNumItems; + } + + return nNewSample; +} + +// play the next item --------------------------------------------------------- +// +int BKGN_StartNextItem( void* dummy ) +{ + AUD_BackGroundPlayer_Start( TRUE ); + + return TRUE; +} + + +// play a sample -------------------------------------------------------------- +// +PRIVATE +void BKGNm_PlaySample( BKGN_Item_s* item ) +{ + SoundParams_s soundParams; + memset( &soundParams, 0, sizeof( SoundParams_s ) ); + + if ( BKGN_nNumItems == 1 ) { + // if only one sample, then we loop that forever + soundParams.flags = SOUNDPARAMS_LOOP; + soundParams.start = 0; + } + + sampleinfo_s* pSampleInfo = AUD_FetchSampleById( item->id ); + + soundParams.volume = pSampleInfo->volume; + soundParams.flags |= SOUNDPARAMS_VOLUME; + + // retrieve the wave from the sampleinfo + audiowave_t wave = pSampleInfo->samplepointer; + AUDs_PlayVoiceBuffer(BKGN_nVoice, wave, &soundParams); + + // add an event to start the next item, after the sample play has stopped + event_s* event = (event_s*) ALLOCMEM( sizeof ( event_s ) ); + + event->type = EVT_TYPE_BKGN_SAMPLE_END; + event->callback = BKGN_StartNextItem; + event->callback_params = NULL; + event->refframe_delay = pSampleInfo->size; + event->flags = EVENT_PARAM_ONESHOT | + EVENT_PARAM_AUTOFREE | + EVENT_PARAM_AUTOTRIGGER; + + EVT_AddEvent( event ); +} + + +// play a cd track ------------------------------------------------------------ +// +PRIVATE +void BKGNm_PlayTrack( BKGN_Item_s* item ) +{ + /* + int tracklength = AUDs_CDGetTrackLength( (short)item->id ); + + if ( tracklength != -1 ) { + + AUDs_CDPlay( (short)item->id, -1, -1 ); + + // add an event to start the next item, after the cdtrack play has stopped + event_s* event = (event_s*) ALLOCMEM( sizeof ( event_s ) ); + + event->type = EVT_TYPE_BKGN_CDTRACK_END; + event->callback = BKGN_StartNextItem; + event->callback_params = NULL; + + event->refframe_delay = FRAME_MEASURE_TIMEBASE * tracklength; + event->flags = EVENT_PARAM_ONESHOT | + EVENT_PARAM_AUTOFREE | + EVENT_PARAM_AUTOTRIGGER; + + EVT_AddEvent( event ); + + } else { + + BKGN_StartNextItem( NULL ); + }*/ + +} + + +// play an audio stream ------------------------------------------------------- +// +PRIVATE +void BKGNm_PlayStream( BKGN_Item_s* item ) +{ + if ( AUDs_PlayAudioStream( item->filename ) ) { + +// MSGOUT( "playing stream %s", item->filename ); + + // specify callback type and flags +// int callbacktype = CBTYPE_STREAM_ENDED | CBFLAG_REMOVE; + + // ensure no dangling callbacks are left around, they might add up +// CALLBACK_DeleteCallback( callbacktype, BKGN_callback_id ); + + // register callback to play next item, after the stream has ended +// BKGN_callback_id = +// CALLBACK_RegisterCallback( callbacktype, BKGN_StartNextItem, (void*) NULL ); + + } else { + +// MSGOUT( "Can't play stream %s", item->filename ); + BKGN_StartNextItem( NULL ); + } +} + +// play an audio stream ------------------------------------------------------- +// +PRIVATE +void BKGNm_PlaySilence( BKGN_Item_s* item ) +{ + // add an event to start the next item, after the silence time has elapsed + event_s* event = (event_s*) ALLOCMEM( sizeof ( event_s ) ); + + event->type = EVT_TYPE_BKGN_SILENCE_END; + event->callback = BKGN_StartNextItem; + event->callback_params = NULL; + event->refframe_delay = FRAME_MEASURE_TIMEBASE * item->id; + event->flags = EVENT_PARAM_ONESHOT | + EVENT_PARAM_AUTOFREE | + EVENT_PARAM_AUTOTRIGGER; + + EVT_AddEvent( event ); + +} + + +// start playing the background sound by randomly picking one of the samples -- +// +int AUD_BackGroundPlayer_Start( int fromevent ) +{ + if ( DISABLE_MUSIC_FUNCTIONS ) + return FALSE; + + if ( BKGN_nNumItems > 0 ) { + if(fromevent!=42){ + if ( BKGN_Started ) { + AUD_BackGroundPlayer_Stop(); + if ( !fromevent ) { + EVT_RemoveEventType( EVT_TYPE_BKGN_SAMPLE_END ); + EVT_RemoveEventType( EVT_TYPE_BKGN_CDTRACK_END ); + } + } + } + + if ( BKGN_nNumItems == 1 ) { + BKGN_nCurrentItem = 0; + } else { + BKGN_nCurrentItem = BKGNm_ChooseNewItem(); + } + + BKGN_Item_s* item = BKGN_GetItem( BKGN_nCurrentItem ); + + if ( item != NULL ) { + switch ( item->type ) { + + case BKGN_ITEM_TYPE_SAMPLE: + BKGNm_PlaySample( item ); + break; + + case BKGN_ITEM_TYPE_CDTRACK: + BKGNm_PlayTrack( item ); + break; + + case BKGN_ITEM_TYPE_STREAM: + BKGNm_PlayStream( item ); + break; + + case BKGN_ITEM_TYPE_SILENCE: + BKGNm_PlaySilence( item ); + break; + + default: + break; + } + + BKGN_Started = TRUE; + + return TRUE; + } + } + + return FALSE; + +} + + +// ---------------------------------------------------------------------------- +// +extern int FloatingMenuStatusWindowActive(); + + +// maintain background sound playing ------------------------------------------ +// +int AUD_BackGroundPlayer_Maintain() +{ + if ( DISABLE_AUDIO_FUNCTIONS || AUX_DISABLE_SOUNDEFFECTS ) { + // stop playing the background sound if currently playing + if ( BKGN_Started ) { + AUD_BackGroundPlayer_Stop(); + EVT_RemoveEventType( EVT_TYPE_BKGN_SAMPLE_END ); + + EVT_RemoveEventType( EVT_TYPE_BKGN_CDTRACK_END ); + } + + return FALSE; + } + + // maintain the background sound + if ( AUX_AUTOSTART_BACKGROUNDPLAYER ) { + + if ( GAME_MODE_ACTIVE() && InGameLoop ) { + + // start background sound, if in game loop, and not yet started + if ( !AUD_BackGroundPlayer_IsPlaying() ) { + AUD_BackGroundPlayer_Start( FALSE ); + return TRUE; + } + + } else if ( !FloatingMenuStatusWindowActive() ) { + + // stop background sound, if out of game loop + if ( AUD_BackGroundPlayer_IsPlaying() ) { + AUD_BackGroundPlayer_Stop(); + EVT_RemoveEventType( EVT_TYPE_BKGN_SAMPLE_END ); + EVT_RemoveEventType( EVT_TYPE_BKGN_CDTRACK_END ); + return TRUE; + } + } + } + + return TRUE; +} + + +// list all samples added to the list of background samples ------------------- +// +void AUD_BackGroundPlayer_List() +{ + int nItem = 0; + char current; + + for ( BKGN_Item_s* scan = BKGN_items_head; scan != NULL; nItem++) { + BKGN_Item_s* next = scan->next; + + if ( ( nItem == BKGN_nCurrentItem ) && BKGN_Started ) { + + current = '*'; + + } else if ( scan->groupnext ) { + + current = '|'; + + } else { + + current = ' '; + } + + switch( scan->type ) { + + case BKGN_ITEM_TYPE_SAMPLE: + { + sampleinfo_s* pSampleInfo = AUD_FetchSampleById( scan->id ); + sprintf( paste_str, "%c [%02d] sample id %u name (%s) volume %u", + current, nItem, (unsigned int)scan->id, + pSampleInfo->name, (unsigned int)pSampleInfo->volume ); + CON_AddLine( paste_str ); + } + + break; + + /*case BKGN_ITEM_TYPE_CDTRACK: + { + int tracklength = AUDs_CDGetTrackLength( (short)scan->id ); + if ( tracklength != -1 ) { + int mins = tracklength / 60; + int secs = tracklength - ( mins * 60 ); + + sprintf( paste_str, "%c [%02d] track %02d length %02d:%02d", current, nItem, + scan->id, mins, secs ); + } else { + + sprintf( paste_str, "%c [%02d] track %02d (no cd available)", current, nItem, + scan->id ); + + } + CON_AddLine( paste_str ); + } + break; + */ + case BKGN_ITEM_TYPE_STREAM: + { + sprintf( paste_str, "%c [%02d] stream %s", current, nItem, scan->filename ); + CON_AddLine( paste_str ); + } + break; + + case BKGN_ITEM_TYPE_SILENCE: + { + sprintf( paste_str, "%c [%02d] silence %u seconds", current, nItem, (unsigned int)scan->id ); + CON_AddLine( paste_str ); + } + break; + + default: + break; + } + + scan = next; + } +} + + +// stop playing the backgroundplayer ------------------------------------------ +// +int AUD_BackGroundPlayer_Stop() +{ + BKGN_Item_s* item = BKGN_GetItem( BKGN_nCurrentItem ); + + if ( item != NULL ) { + switch( item->type ) { + + case BKGN_ITEM_TYPE_SAMPLE: + AUDs_StopVoice( BKGN_nVoice, FALSE ); + break; + + /*case BKGN_ITEM_TYPE_CDTRACK: + AUDs_CDStop(); + break; + */ + case BKGN_ITEM_TYPE_STREAM: + AUDs_StopAudioStream(); + break; + + case BKGN_ITEM_TYPE_SILENCE: + // nothing needs to be done to stop silence + break; + + default: + break; + } + + BKGN_Started = FALSE; + + return TRUE; + } + + return FALSE; +} + + +// check whether a sample is playing ------------------------------------------ +// +int AUD_BackGroundPlayer_IsPlaying() +{ + return BKGN_Started; +} + + +// console command for starting the background sample playing ----------------- +// +PRIVATE +int Cmd_BKGN_START( char *bkgnstr ) +{ + ASSERT( bkgnstr != NULL ); + HANDLE_COMMAND_DOMAIN_SEP( bkgnstr ); + + // start playing the background sound + AUD_BackGroundPlayer_Start( FALSE ); + + return TRUE; +} + + +// console command for stopping the background sample playing ----------------- +// +PRIVATE +int Cmd_BKGN_STOP( char *bkgnstr ) +{ + ASSERT( bkgnstr != NULL ); + HANDLE_COMMAND_DOMAIN_SEP( bkgnstr ); + + // stop playing the background sound + AUD_BackGroundPlayer_Stop(); + EVT_RemoveEventType( EVT_TYPE_BKGN_SAMPLE_END ); + EVT_RemoveEventType( EVT_TYPE_BKGN_CDTRACK_END ); + + return TRUE; +} + + +// key table for background sound loading ------------------------------------- +// +static key_value_s bkgn_add_key_value[] = { + + { "sample", NULL, KEYVALFLAG_NONE | KEYVALFLAG_PARENTHESIZE }, + { "track", NULL, KEYVALFLAG_NONE }, + { "stream", NULL, KEYVALFLAG_NONE }, + { "silence", NULL, KEYVALFLAG_NONE }, + + + + { NULL, NULL, KEYVALFLAG_NONE }, +}; + +enum { + + KEY_BKGN_ADD_SAMPLE, + KEY_BKGN_ADD_TRACK, + KEY_BKGN_ADD_STREAM, + KEY_BKGN_ADD_SILENCE +}; + + +// console command for adding a background sample ----------------------------- +// +PRIVATE +int Cmd_BKGN_ADD( char *bkgnstr ) +{ + //NOTE: + //CONCOM: + // bkgn_add_command ::= 'bkgn.add' + // itemspec ::= | | + // | + // samplespec ::= 'sample' + // trackspec ::= 'track' + // streamspec ::= 'stream' + // silencespec ::= 'silence' + + ASSERT( bkgnstr != NULL ); + HANDLE_COMMAND_DOMAIN_SEP( bkgnstr ); + + // scan out all values to bkgn keys + if ( !ScanKeyValuePairs( bkgn_add_key_value, bkgnstr ) ) + return TRUE; + + char *samplename = bkgn_add_key_value[ KEY_BKGN_ADD_SAMPLE ].value; + + char *streamname = bkgn_add_key_value[ KEY_BKGN_ADD_STREAM ].value; + + int track = -1; + + if( bkgn_add_key_value[ KEY_BKGN_ADD_TRACK ].value != NULL ) { + ScanKeyValueInt( &bkgn_add_key_value[ KEY_BKGN_ADD_TRACK ], &track ); + } + + int silenceseconds = -1; + + if( bkgn_add_key_value[ KEY_BKGN_ADD_SILENCE ].value != NULL ) { + ScanKeyValueInt( &bkgn_add_key_value[ KEY_BKGN_ADD_SILENCE ], &silenceseconds ); + + } + + //FIXME: need to split this in bkgn.add.sample and bkgn.add.track + if( track != -1 ) { + + // add a track to the list of background items + if( AUD_BackGroundPlayer_AddTrack( track ) == FALSE ) { + CON_AddLine( invalid_parameter ); + return TRUE; + } + + } else { + + if ( samplename != NULL ) { + + // add a sample to the list of background items + if( AUD_BackGroundPlayer_AddSample( samplename ) == FALSE ) { + CON_AddLine( invalid_sample_specified ); + return TRUE; + } + + } else if ( streamname != NULL ) { + + // add a stream to the list of background items + if( AUD_BackGroundPlayer_AddStream( streamname ) == FALSE ) { + CON_AddLine( invalid_stream_specified ); + return TRUE; + } + + } else if ( silenceseconds != -1 ) { + + // add silence to the list of background items + if( AUD_BackGroundPlayer_AddSilence( silenceseconds ) == FALSE ) { + CON_AddLine( invalid_parameter ); + return TRUE; + } + } + } + + return TRUE; +} + + +// key table for background sound loading ------------------------------------- +// +static key_value_s bkgn_rmv_key_value[] = { + + { "sample", NULL, KEYVALFLAG_NONE | KEYVALFLAG_PARENTHESIZE }, + { "track", NULL, KEYVALFLAG_NONE }, + { "item", NULL, KEYVALFLAG_NONE }, + + { NULL, NULL, KEYVALFLAG_NONE }, +}; + +enum { + + KEY_BKGN_RMV_SAMPLE, + KEY_BKGN_RMV_TRACK, + KEY_BKGN_RMV_ITEM +}; + + +// console command for adding a background sample ----------------------------- +// +PRIVATE +int Cmd_BKGN_REMOVE( char *bkgnstr ) +{ + //NOTE: + //CONCOM: + // bkgn_remove_command ::= 'bkgn.remove' + // itemspec ::= | | + // idspec ::= 'id' + // samplespec ::= 'sample' + // trackspec ::= 'track' + + ASSERT( bkgnstr != NULL ); + HANDLE_COMMAND_DOMAIN_SEP( bkgnstr ); + + // scan out all values to bkgn keys + if ( !ScanKeyValuePairs( bkgn_rmv_key_value, bkgnstr ) ) + return TRUE; + + char *samplename = bkgn_rmv_key_value[ KEY_BKGN_RMV_SAMPLE ].value; + int track = -1; + + if ( bkgn_rmv_key_value[ KEY_BKGN_RMV_TRACK ].value != NULL ) { + ScanKeyValueInt( &bkgn_rmv_key_value[ KEY_BKGN_RMV_TRACK ], &track); + } + + int item = -1; + if ( bkgn_rmv_key_value[ KEY_BKGN_RMV_ITEM ].value != NULL ) { + ScanKeyValueInt( &bkgn_rmv_key_value[ KEY_BKGN_RMV_ITEM ], &item ); + } + + if ( item != -1 ) { + + // remove a track from the list of background items + if ( !AUD_BackGroundPlayer_RemoveItem( item ) ) { + CON_AddLine( invalid_parameter ); + return TRUE; + + } + + } else { + + //NOTE: + // these are only here for legacy support + + if ( track != -1 ) { + + // remove a track from the list of background items + if ( !AUD_BackGroundPlayer_RemoveTrack( track ) ) { + CON_AddLine( invalid_parameter ); + return TRUE; + } + + } else { + + // remove a sample from the list of background samples + if ( !AUD_BackGroundPlayer_RemoveSample( samplename ) ) { + CON_AddLine( invalid_sample_specified ); + return TRUE; + } + } + + } + + return TRUE; + +} + + +// console command for listing all the background samples --------------------- +// +PRIVATE +int Cmd_BKGN_LIST( char *bkgnstr ) +{ + //NOTE: + //CONCOM: + // bkgn_list_command ::= 'bkgn.list' + + ASSERT( bkgnstr != NULL ); + HANDLE_COMMAND_DOMAIN_SEP( bkgnstr ); + + // list all added samples + AUD_BackGroundPlayer_List(); + + return TRUE; +} + + +// key table for item grouping ------------------------------------------------ +// +static key_value_s bkgn_group_key_value[] = { + + + { "item", NULL, KEYVALFLAG_MANDATORY }, + + { NULL, NULL, KEYVALFLAG_NONE }, +}; + +enum { + + KEY_BKGN_ITEM +}; + + +// console command for grouping two tracks ------------------------------------ +// +PRIVATE +int Cmd_BKGN_GROUP( char *bkgnstr ) +{ + //NOTE: + //CONCOM: + // bkgn_group_command ::= 'bkgn.group' + // itemspec ::= 'item' + + ASSERT( bkgnstr != NULL ); + HANDLE_COMMAND_DOMAIN_SEP( bkgnstr ); + + // scan out all values to bkgn keys + if ( !ScanKeyValuePairs( bkgn_group_key_value, bkgnstr ) ) + return TRUE; + + int item = -1; + + if( bkgn_group_key_value[ KEY_BKGN_ITEM ].value != NULL ) { + ScanKeyValueInt( &bkgn_group_key_value[ KEY_BKGN_ITEM ], &item); + } + + // group specified item with next in list + if ( item != -1 ) { + + // get item + BKGN_Item_s* listitem = BKGN_GetItem( item ); + + ASSERT(listitem != NULL); + + if ( listitem->groupnext ) { + + listitem->groupnext = FALSE; + + } else { + + listitem->groupnext = TRUE; + } + + } + + return TRUE; +} + + +// module registration function ----------------------------------------------- +// +REGISTER_MODULE( AUD_BKGN ) +{ + user_command_s regcom; + memset( ®com, 0, sizeof( user_command_s ) ); + + // register "bkgn.start" command + regcom.command = "bkgn.start"; + regcom.numparams = 0; + regcom.execute = Cmd_BKGN_START; + regcom.statedump = NULL; + CON_RegisterUserCommand( ®com ); + + // register "bkgn.stop" command + regcom.command = "bkgn.stop"; + regcom.numparams = 0; + regcom.execute = Cmd_BKGN_STOP; + regcom.statedump = NULL; + CON_RegisterUserCommand( ®com ); + + // register "bkgn.add" command + regcom.command = "bkgn.add"; + regcom.numparams = 1; + regcom.execute = Cmd_BKGN_ADD; + regcom.statedump = NULL; + CON_RegisterUserCommand( ®com ); + + // register "bkgn.remove" command + regcom.command = "bkgn.remove"; + regcom.numparams = 1; + regcom.execute = Cmd_BKGN_REMOVE; + regcom.statedump = NULL; + CON_RegisterUserCommand( ®com ); + + // register "bkgn.list" command + regcom.command = "bkgn.list"; + regcom.numparams = 0; + regcom.execute = Cmd_BKGN_LIST; + regcom.statedump = NULL; + CON_RegisterUserCommand( ®com ); + + // register "bkgn.group" command + regcom.command = "bkgn.group"; + regcom.numparams = 0; + regcom.execute = Cmd_BKGN_GROUP; + regcom.statedump = NULL; + CON_RegisterUserCommand( ®com ); + + // register "bkgn.shuffle" command + int_command_s intregcom; + memset( &intregcom, 0, sizeof( int_command_s ) ); + + intregcom.command = "bkgn.shuffle"; + intregcom.bmin = 0; + intregcom.bmax = 1; + intregcom.intref = &BKGN_shuffle; + intregcom.realize = NULL; + intregcom.fetch = NULL; + CON_RegisterIntCommand( &intregcom ); +} + -- cgit v1.2.3