reman3/Rayman_X/cpa/tempgrp/SND/src/sndtheme.c

931 lines
27 KiB
C

/*
//////////////////////////////////////////////////////////
// Module SNDTHEME:gestion des ressources THEME (melodies dynamigues
//////////////////////////////////////////////////////////
*/
#include "SNDinc.h"
#include "sndres.h"
#include "sndtheme.h"
#include "sndplay.h"
#ifndef NO_ACP_SOUND
#ifndef DISABLE_THEME
/*-----variavles locales*/
typedef struct active_theme_ active_theme;
struct active_theme_{
SndBool_field_decl(bActive); /*TRUE if voice is valid (themebeeing played)*/
SndBool_field_decl(bSleeping); /*TRUE when Outro has been played*/
SndBool_field_decl(bTransAsked); /*TRUE if transition to a new THEME asked*/
SndBool_field_decl(bTransiting); /*TRUE if transition if currently running (it no more impossible to avoid playing the future new theme)*/
SndBool_field_decl(bOutroAsked); /*TRUE if transition if currently running (it no more impossible to avoid playing the future new theme)*/
tduRefRes uCurrentThemeRes; /*THEME ressource currently played*/
hThemePart hLoopingPart; /*re-loop for 2° level loop (if any)*/
long lLoopingPartIndice; /*indice of this part*/
long lNbLoopLeft; /*number of loop remaining (set to NbLoops at first run)*/
unsigned long ulNbLoopDone; /*number of main-loop*/
hThemePart hCurrentPart; /*current part (the one mixed)*/
long lCurrentPartIndice; /*indice of this part*/
long lVoice; /*SNDPLAY voice associated with this theme*/
hThemePart hNextPart; /*expected res-part (call to SetNextTransition); can be cancelled with a nex call to SetNextTransition*/
long lNextPartIndice; /*indice od this part*/
tduRefRes uNextRes; /*res for this part*/
tduRefRes uAskedThemeRes; /*THEME asked for a transition (if any)*/
tduRefRes uGoingToThemeRes; /*first resource part associated with this expected theme (INVALID_RES if theme is finishing)*/
tdstThemePart *pTransitingPart; /*ptr onto part played just before uGoingToThemeRes part*/
SND_td_pfn_vSoundCallback pfnFctCallback; /*client callback function; to be called on transitions*/
long lParCallback; /*parameter to be used with pfnFctCallback*/
SndBool *pbValid;
SoundParam *pstParam; /*current SoundParam for the Theme (last call to SetParamTheme)*/
long lSizeParam; /*size of this SoundParam*/
};
static active_theme g_stTheme; /*current active THEME; there could be only 1 active THEME*/
static SndBool g_bWorkingTheme=FALSE; /*TRUE when a THEME is playing*/
/*
For the current part
!if bActive==FALSE ->theme is not active
!if bActive=TRUE, uCurentThemeRes is currently beeing played
!
!+if bTransiting==FALSE
!! if lCurrentParInidce==-1, intro is currently beeing played
!! otherwise, part ulCureentPartIndice is currently beeing played
!!otherwise
!! transiting to new theme uGoingToThemeRes
!
!uCurrentRes=low-level resource associated with ulCureentPartIndice
!lVoice=low-level voice associated
For the expected part
!if bActive=TRUE, we plan to next part, or the appropiate bridge, or first part of next theme
!
!+if bTansiting==TRUE
!!+ if uGoingToThemeRes=INVALID,
!!! we will stop
!!! otherwise
!!! 1° part of theme uGoingToThemeRes will be played
!!
!!
!!otherwise
!!+if bTransAsked==TRUE
!!!
Evtx: jouer la theme x
Theme1:2 parts A et B bouclantes;bridge In I;bridge out vers theme 2=O1;vers theme 3=O3;defaut O
Theme2:3 parts a,b,c bouclantes;bridge In ?;pas de bridge out par defaut;bridge out vers themes ?
Theme3:n parts r,s... ;bridge In ?;bridge vers theme 2 O2
| Evt1| Evt3 Evt2 | |
| ! | ! ! | |
| 0 ! |<---- them 1 ------+---+-------|<--theme2->| 0
| ! | ! ! | |
| ! | I . A . B . A . B ! B ! B . O1| a . b . c |
| ! | . . . . ! ! . | . . |
bActive | F ! | T . T . T . T . T ! T ! T . T | T . T . T | F
lCurrentTheme | x ! | 1 . 1 . 1 . 1 . 1 ! 1 ! 1 . 1 | 2 . 2 . 2 | x
lCurrentPartIndice | x ! | -1. 0 . 1 . 0 . 1 ! 1 ! 1 . x | 0 . 1 . 2 | x
lNextPartIndice | x ! | 0 . 1 . 0 . 1 . 0 ! x ! x . x | 1 . 2 . x | x
bTransAsked | x ! | F . F . F . F . F ! T ! T . F | F . F . F | x
uThemeAsked | x ! | x . x . x . x . x ! 3 ! 2 . x | x . x . x | x
bTransiting | x ! | F . F . F . F . F ! F ! F . T | F . F . T | x
uGoingToThemeRes | x ! | x . x . x . x . x ! x ! x . 2 | x . x .INV| x
P-1,0 S1 S0 S1 S0 SO2 SO1 Sa Sb Sc SI
p-1 p0 p1 p0 p1 pO1 pa pb pc
| Evt1| Evt3 Evt2 | |
| ! | ! ! | |
| 0 ! |<--- them1 +-------+-->|<them3>|<--theme 2...
| ! | ! ! | |
| ! | I . A . B ! B . O3! O3| r . O2| a . b
| ! | . . ! . ! | . |
bActive | F ! | T . T . T ! T . T ! T | T . T | T . T ...
lCurrentTheme | x ! | 1 . 1 . 1 ! 1 . 1 ! 1 | 3 . 3 | 2 . 2 ...
lCurrentPartIndice | x ! | -1. 0 . 1 ! 1 . x ! x | 0 . x | 0 . 1 ...
lNextPartIndice | x ! | 0 . 1 . 0 ! x . x ! x | 1 . x | 1 . 2 ...
bTransAsked | x ! | F . F . F ! T . F ! T | T . F | F . F ...
uThemeAsked | x ! | x . x . x ! 3 . x ! 2 ! 2 . x | x . x ...
bTransiting | x ! | F . F . F ! F . T ! T | F . T | F . F ...
uGoingToThemeRes | x ! | x . x . x ! x . 3 ! 3 | x . 2 | x . x ...
PI,A SB SA SO3 Sr x SO2 Sa Sb Sc SI
pI pA pB p03 pr pO2 pa pb pc
| Evt1| Evt3 |
| ! | ! |
| 0 ! |<--+-them1---->|<-----them3...
| ! | ! |
| ! | I ! I . A . O3| r . s
| ! | ! . !
bActive | F ! | T ! T . T . T | T . T ...
lCurrentTheme | x ! | 1 ! 1 . 1 . 1 | 3 . 3 ...
lCurrentPartIndice | x ! | -1! -1. 0 . x | 0 . 1 ...
lNextPartIndice | x ! | 0 ! 0 . x . x | 1 . 2 ...
bTransAsked | x ! | F ! T . T . F | F . F ...
uThemeAsked | x ! | x ! 3 . 3 . x ! x . x ...
bTransiting | x ! | F ! F . F . T | F . F ...
uGoingToThemeRes | x ! | x ! x . x . 3 | x . x ...
PI,A x S03 Sr Sr
p-1 pA pO3 pr ps
| Evt1| |
| ! | |
| 0 ! |<-them1--->| 0
| ! | |
| ! | I . A . O |
| ! | . !
bActive | F ! | T . T . T | F...
lCurrentTheme | x ! | 1 . 1 . 1 | x...
lCurrentPartIndice | x ! | -1. 0 . x | x...
lNextPartIndice | x ! | 0 . x . x | x...
bTransAsked | x ! | F . F . F | x...
uThemeAsked | x ! | x . x . x ! x...
bTransiting | x ! | F . F . T | x...
uGoingToThemeRes | x ! | x . x .INV| x...
PI,A SO SINV
pI pA pO
*/
/*----update field describing next part (use current part)*/
/* update hNextPart and lNextPartIndice */
/* use ulCurrentPartIndice,hCurrentPart,hLoopingPart,lNbLoopLeft*/
SndBool raj_next_part(active_theme *theme)
{
tdstTypeThemeMem *pstThemeRes;
hThemePart hPart;
int i;
SndBool bFound=FALSE;
long lIndicePart;
SndBool bMainLoopEnded=FALSE;
/*---find the next part*/
/*
if (theme->bOutroAsked)
{
theme->bOutroAsked=FALSE;
theme->uNextRes=theme->uCurrentThemeRes.pstPtr->uRes.stTheme.pstPartOutro->uRes;
return TRUE;
}*/
if (theme->bTransiting)
{
theme->bTransiting=FALSE;
if (theme->uGoingToThemeRes.pstPtr==SND_C_RES_FANTOME_PTR)
{/*theme is over*/
theme->bSleeping=TRUE;
return FALSE;
}
theme->uCurrentThemeRes=theme->uGoingToThemeRes;
if (theme->bOutroAsked)
{/*transition outro->1°part of new theme*/
theme->bOutroAsked=FALSE;
theme->lNextPartIndice=0;
theme->hNextPart=SNDLST2_M_StaticGetFirstElement(&theme->uCurrentThemeRes.pstPtr->uRes.stTheme);
theme->uNextRes=theme->hNextPart->uRes;
return TRUE;
}
}
pstThemeRes=&(theme->uCurrentThemeRes.pstPtr->uRes.stTheme);
/*is there a second level loop ending?*/
if ((theme->hCurrentPart->bLoopEnd) && (theme->lNbLoopLeft))
{/*there is a second level loop*/
theme->lNbLoopLeft--;
if (theme->hLoopingPart)
{
theme->hNextPart=theme->hLoopingPart;
theme->lNextPartIndice=theme->lLoopingPartIndice;
theme->uNextRes=theme->hNextPart->uRes;
}
else
{
theme->hNextPart=SNDLST2_M_StaticGetFirstElement(pstThemeRes);
theme->lNextPartIndice=0;
theme->uNextRes=theme->hNextPart->uRes;
}
}
else
{/*no loop*/
if (!theme->lNbLoopLeft)
theme->hLoopingPart=NULL;
/*no more loop*/
theme->lNextPartIndice++;
/*main loop?*/
if ((unsigned long)theme->lNextPartIndice>=theme->uCurrentThemeRes.pstPtr->uRes.stTheme.ulNbParts)
{/*yes, main loop*/
if (theme->uCurrentThemeRes.pstPtr->uRes.stTheme.ulNbLoops!=C_THEME_MAINLOOP_INFINITE)
{
theme->ulNbLoopDone++;
if (theme->ulNbLoopDone>=theme->uCurrentThemeRes.pstPtr->uRes.stTheme.ulNbLoops)
bMainLoopEnded=TRUE;
}
if (bMainLoopEnded)
{/*end of main-loop*/
if (theme->uCurrentThemeRes.pstPtr->uRes.stTheme.pstPartOutro)
{
theme->bOutroAsked=TRUE;
theme->bTransiting=TRUE;
theme->uNextRes=theme->uCurrentThemeRes.pstPtr->uRes.stTheme.pstPartOutro->uRes;
}
else
{
theme->bSleeping=TRUE;
return FALSE;
}
theme->uGoingToThemeRes=SND_RES_FANTOME;
}
else
{/*re-loop*/
theme->lNextPartIndice=pstThemeRes->ulStartLoop;
SNDLST2_M_StaticGetElementNumber(pstThemeRes,theme->hNextPart,theme->lNextPartIndice,i);
theme->uNextRes=theme->hNextPart->uRes;
/*retourne-t-on a l'interieur d'une boucle interne*/
hPart=theme->hNextPart;
bFound=FALSE;
lIndicePart=pstThemeRes->ulStartLoop;
while (hPart)
{
if (hPart->bLoopStart)
{
bFound=TRUE;
theme->hLoopingPart=hPart;
theme->lLoopingPartIndice=lIndicePart;
theme->lNbLoopLeft=theme->hLoopingPart->lNbLoops;
break;
}
hPart=SNDLST2_M_StaticGetPrevElement(hPart);
lIndicePart--;
if (lIndicePart<0)
break;
if (hPart && hPart->bLoopEnd)
break;
}
}
}
else
{
theme->hNextPart=SNDLST2_M_StaticGetNextElement(theme->hNextPart);
theme->uNextRes=theme->hNextPart->uRes;
}
}
/*debut de rebouclage interne ?*/
if (theme->hNextPart->bLoopStart && !theme->hLoopingPart)
{
theme->hLoopingPart=theme->hNextPart;
theme->lLoopingPartIndice=theme->lNextPartIndice;
theme->lNbLoopLeft=theme->hLoopingPart->lNbLoops;
}
return TRUE;
}
/*--------- */
/*return TRUE if change theme by fade; FALSE if new part is chained*/
SndBool change_theme(active_theme *theme,tduRefRes new_theme)
{
tdeTypeTransition transition;
if (theme->bSleeping)
{
transition=TRANSITION_ATENDOFPART;
}
else
{
transition=theme->hCurrentPart->eTransition;
}
theme->bOutroAsked=FALSE;
theme->bTransiting=TRUE;
theme->bSleeping=FALSE;
theme->uGoingToThemeRes=new_theme;
if (!new_theme.pstPtr->uRes.stTheme.ulNbParts)
{/*new theme is empty ->OUT*/
theme->hNextPart=NULL;
theme->lNextPartIndice=-1;
theme->uNextRes=SND_RES_FANTOME;
return FALSE;/*C_PLAY_FAILED;*/
}
/*init theme*/
theme->hLoopingPart=NULL;
theme->lLoopingPartIndice=-1;
theme->lNbLoopLeft=-1;
theme->ulNbLoopDone =0;
/*---find the 1° part */
theme->lNextPartIndice=0;
theme->hNextPart=SNDLST2_M_StaticGetFirstElement(&new_theme.pstPtr->uRes.stTheme);
if ((transition!=TRANSITION_OUTRO) || (!theme->uCurrentThemeRes.pstPtr->uRes.stTheme.pstPartOutro))
theme->uNextRes=theme->hNextPart->uRes;
else
{
theme->bOutroAsked=TRUE;
theme->uNextRes=theme->uCurrentThemeRes.pstPtr->uRes.stTheme.pstPartOutro->uRes;
}
/*is it a start-loop part ?*/
if (theme->hNextPart->bLoopStart)
{
theme->hLoopingPart=theme->hNextPart;
theme->lLoopingPartIndice=theme->lNextPartIndice;
theme->lNbLoopLeft=theme->hLoopingPart->lNbLoops;
}
switch (transition)
{
case TRANSITION_CROSSFADE:
return TRUE;
break;
case TRANSITION_ATENDOFPART:
case TRANSITION_OUTRO:
return FALSE;
break;
}
return FALSE;
}
/*theme_res=nouvelle ressource theme*/
void start_new_theme(active_theme *theme,tduRefRes theme_res)
{
tdstTypeThemeMem *pstThemeRes;
pstThemeRes=&(theme_res.pstPtr->uRes.stTheme);
theme->uCurrentThemeRes=theme_res;
theme->bTransiting=FALSE;
theme->bTransAsked=FALSE;
theme->bOutroAsked=FALSE;
theme->bSleeping=FALSE;
if (!theme_res.pstPtr->uRes.stTheme.ulNbParts)
{/*pas de sequence,->OUT*/
theme->hCurrentPart=NULL;
g_bWorkingTheme=FALSE;
return ;/*C_PLAY_FAILED;*/
}
/*init du theme*/
theme->hLoopingPart=NULL;
theme->lLoopingPartIndice=-1;
theme->lNbLoopLeft=-1;
theme->ulNbLoopDone =0;
/*---trouver le 1° part */
theme->lCurrentPartIndice=0;
theme->hCurrentPart=SNDLST2_M_StaticGetFirstElement(&theme_res.pstPtr->uRes.stTheme);
theme->lNextPartIndice=0;
theme->hNextPart=theme->hCurrentPart;
theme->uNextRes=theme->hNextPart->uRes;
/*debut de rebouclage interne ?*/
if (theme->hCurrentPart->bLoopStart)
{
theme->hLoopingPart=theme->hCurrentPart;
theme->lLoopingPartIndice=theme->lCurrentPartIndice;
theme->lNbLoopLeft=theme->hLoopingPart->lNbLoops;
}
/*---trouver le prochain part*/
raj_next_part(theme);
}
/*------- Fonction de transition*/
void SND_CALL fn_Transition(long par)
{
active_theme *theme=(active_theme*)par;
tduRefRes NextRes;
if (g_bWorkingTheme || !theme->bActive || theme->bSleeping)
return;
theme->lCurrentPartIndice=theme->lNextPartIndice;
theme->hCurrentPart=theme->hNextPart;
if (!raj_next_part(theme))
/*if (!trans_theme(&theme))*/
{/*le theme est mort (deriniere opart finie)*/
//theme->bActive=FALSE;
if (theme->pbValid!=NULL)
theme->pbValid=FALSE;
if (theme->pfnFctCallback!=NULL)
(*(theme->pfnFctCallback))(theme->lParCallback);
}
else
{
/*_RPT2(_CRT_WARN,"->%d(%d)\n",theme.lCurrentPartIndice,theme.lNextPartIndice);*/
NextRes=SND_fn_tduGetLowestResourceSnd(theme->uNextRes,theme->pstParam,TRUE);
SND_fn_bSetNextTransitionSnd(theme->lVoice,NextRes);
}
}
#endif /*DISABLE_THEME*/
/*---------------------------------------------------------------------*/
/* pour debogage*/
/* Retourne FALSE si theme non actif*/
/* sinon: id_part=indice de la part en cours (0 à N)*/
/* id_bridge=indice du bridge en cours*/
/* THEMEPOSITION_BRIDGEIN si bridge in en cours*/
/* THEMEPOSITION_NOBRIDGE si pas de bridge en cours*/
/*---------------------------------------------------------------------*/
SndBool SND_fn_bGetThemePosition(tduRefRes *current_theme,long* id_part,long* id_loop)
{
#ifndef DISABLE_THEME
active_theme *theme=&g_stTheme;
if (!theme->bActive)
return FALSE;
*current_theme=theme->uCurrentThemeRes;
*id_part=theme->lCurrentPartIndice;
*id_loop=theme->lNbLoopLeft;
return TRUE;
#else
return FALSE;
#endif
}
/*---------------------------------------------------------------------*/
/* pour debogage*/
/* Retourne FALSE si aucune transition demandee*/
/* sinon: id_part=indice de la part en cours (0 à N)*/
/* id_bridge=indice du bridge en cours*/
/* THEMEPOSITION_BRIDGEIN si bridge in en cours*/
/* THEMEPOSITION_NOBRIDGE si pas de bridge en cours*/
/*---------------------------------------------------------------------*/
SndBool SND_fn_bGetAskedTheme(tduRefRes *asked_theme,SndBool *transiting)
{
#ifndef DISABLE_THEME
active_theme *theme=&g_stTheme;
if (!theme->bActive || !theme->bTransAsked)
return FALSE;
*asked_theme=theme->uAskedThemeRes;
*transiting=theme->bTransiting;
return TRUE;
#else
return FALSE;
#endif
}
/*-----------------------------------------------------*/
/*---------------------------------------------------------------------*/
/* InitTheme: init theme module capabilities*/
/*---------------------------------------------------------------------*/
void SND_fn_vInitTheme(void)
{
#ifndef DISABLE_THEME
active_theme *theme=&g_stTheme;
theme->pstParam=NULL;
theme->lSizeParam=0;
theme->bActive=FALSE;
#endif
}
void SND_fn_vDesInitTheme(void)
{
}
/*---------------------------------------------------------------------*/
/* ConvertResDiskToMemThjeme: gen_re une blockresourcemem valide*/
/* Entrees:disk=block ressource disk à exploiter*/
/* mem=block resource mem à initialiser*/
/* ptrBegin=non exploite*/
/* Sortie:neant*/
/*---------------------------------------------------------------------*/
void SND_fn_vConvertResDiskToMemTheme(tdstBlockResourceDisk* disk
,tdstBlockResourceMem *mem
,void* ptrBegin)
{
#ifndef DISABLE_THEME
mem->Id=disk->Id;
mem->eType=disk->eType;
mem->eStorage=disk->eStorage;
mem->ucVolume=disk->ucVolume;
mem->bIsLoaded=TRUE;
/*partie specifique au type de ressource*/
mem->uRes.stTheme.ulStartLoop = disk->uRes.stTheme.ulStartLoop;
mem->uRes.stTheme.ulNbParts= disk->uRes.stTheme.ulNbParts;
mem->uRes.stTheme.ulNbLoops= disk->uRes.stTheme.ulNbLoops;
mem->uRes.stTheme.rFadeDuration= disk->uRes.stTheme.rFadeDuration;
/*SNDLST2_M_StaticInitAnchor(&(mem->uRes.stTheme));*/
/*pResMem->uRes.stTheme will be initialized by Script library*/
#endif
}
#ifndef NO_ACP_SCRIPT
SndBool SND_fn_bLoadResScriptTheme(tdstBlockResourceDisk *disk,tdstBlockResourceMem *mem)
{
SND_fn_vConvertResDiskToMemTheme(disk,mem,NULL);
return TRUE;
}
#endif
#ifndef NO_ACP_LDBIN
SndBool SND_fn_bLoadResBinaryTheme(tdstBlockResourceDisk *_pBRDisk,tdstBlockResourceMem *_pBRMem,char *pDataBloc)
{
#ifndef DISABLE_THEME
/*convert Binary reference to Mem reference*/
tdstThemePart *pPartArray,*pPart;
int iPos;
/* Convert the ulDataOffset member to a pointer:*/
pPartArray=(tdstThemePart *)(pDataBloc + _pBRDisk->ulDataOffset);
/* Set pointers to part list:*/
SNDLST2_M_StaticSetFirstElement(&_pBRMem->uRes.stTheme,pPartArray);
SNDLST2_M_StaticSetNumberOfElements(&_pBRMem->uRes.stTheme, _pBRDisk->uRes.stTheme.ulNbParts);
/* scan parts:*/
SNDLST2_M_StaticForEachElementOf( &_pBRMem->uRes.stTheme, pPart, iPos)
{
pPart->uRes.pstPtr=SND_fn_pGetBinRes(pPart->uRes.Id);
}
/*part outro is at the end of pPartArray*/
if (_pBRDisk->uRes.stTheme.lOffsetPartOutro!=C_THEME_NO_PARTOUTRO)
{
_pBRMem->uRes.stTheme.pstPartOutro=(tdstThemePartOutro*)((char*)pPartArray+_pBRDisk->uRes.stTheme.lOffsetPartOutro);
_pBRMem->uRes.stTheme.pstPartOutro->uRes.pstPtr=SND_fn_pGetBinRes(_pBRMem->uRes.stTheme.pstPartOutro->uRes.Id);
}
else
_pBRMem->uRes.stTheme.pstPartOutro=NULL;
SND_fn_vConvertResDiskToMemTheme(_pBRDisk,_pBRMem,NULL);
return TRUE;
#else
return FALSE;
#endif
}
#endif /*NO_ACP_LDBIN*/
void SND_fn_vUnLoadResTheme(tdstBlockResourceMem* mem)
{
}
SndBool fn_bCheckTheme(tduRefRes theme_res)
{
hThemePart part;
int i,level_loop;
if (theme_res.pstPtr->uRes.stTheme.ulStartLoop>=theme_res.pstPtr->uRes.stTheme.ulNbParts)
{
snd_assert(0);
return FALSE;
}
#ifdef SNDLST2_StaticIsOptimised
if ((long)theme_res.pstPtr->uRes.stTheme.ulNbParts!=SNDLST2_M_StaticGetNumberOfElements(&theme_res.pstPtr->uRes.stTheme))
{
snd_assert(0);
return FALSE;
}
#endif
level_loop=0;
SNDLST2_M_StaticForEachElementOf(&theme_res.pstPtr->uRes.stTheme,part,i)
{
if (part->bLoopStart)
level_loop++;
if (level_loop>1)
{/*only one level of looping*/
snd_assert(0);
return FALSE;
}
if (part->bLoopEnd)
level_loop--;
if (level_loop<0)
{/*more endloop than begin loop*/
snd_assert(0);
return FALSE;
}
}
if (level_loop!=0)
{/*endloop missing*/
snd_assert(0);
return FALSE;
}
return TRUE;
}
void raj_soundparam_theme(active_theme* theme,SoundParam* par)
{
int size;
if (par)
size=SND_M_lGetSizeOfSoundParam(par);
else
size=0;
if (size)
{
if (size!=theme->lSizeParam)
{
if (theme->pstParam)
theme->pstParam=SND_fn_pvReAllocSndEx(E_ucSndBlockMain,theme->pstParam,size);
else
theme->pstParam=SND_fn_pvMallocSndEx(E_ucSndBlockMain,size);
}
theme->lSizeParam=size;
memcpy(theme->pstParam,par,size);
}
else
{
if (theme->pstParam)
{
SND_fn_vFreeSndEx(E_ucSndBlockMain,theme->pstParam);
theme->pstParam=NULL;
theme->lSizeParam=0;
}
}
}
/*---------------------------------------------------------------------*/
/* PlayTheme: joue une ressource theme*/
/* Entrees:canal=canal souhaite (pour le cas où on veut plusieurs themes simultanement)*/
/* num_res=ressource de type theme à jouer*/
/* par=parametres au lancement*/
/* prio=priorite*/
/* fn_callback=fonction de callback à appeler à a fin de a ressource*/
/* par_callback=parametre à transmettre à la callback*/
/* active=flag à mettre à FALSE si la voie retourner s'invalide*/
/* Sortie:voie/canal associe à la ressource*/
/*---------------------------------------------------------------------*/
long SND_fn_lPlayTheme(long canal,tduRefRes theme_res,SoundParam* par,long prio,SND_td_pfn_vSoundCallback fn_callback,long par_callback,SndBool* valid)
{
#ifndef DISABLE_THEME
tdstTypeThemeMem *pstThemeRes;
SoundParam *pstSoundPar;
active_theme *theme=&g_stTheme;
tduRefRes FirstRes,NextRes;
#ifdef NB_MICRO_MAX
SoundParam stSoundPar;
#endif
snd_assert(canal==C_PLAY_FAILED);/*on ne tolere qu'un seul theme pour l'instant*/
snd_assert(fn_bCheckTheme(theme_res));
/*raj soundparam*/
raj_soundparam_theme(theme,par);
if (((theme->bActive) && (theme_res.pstPtr==theme->uCurrentThemeRes.pstPtr) && !theme->bTransiting)
|| (theme->bTransiting && theme->uGoingToThemeRes.pstPtr!=NULL))
{/*--------- si theme cible et theme source sont identique, on ne fait rien*/
return (long)theme;
}
/*en mettant g_bWorkingTheme à TRUE, on empeche l'occurence de la fonction de Callback*/
/* ->il faut absolument qu'un PlayTransition ou SetNextTransition soit fait*/
g_bWorkingTheme=TRUE;
#ifdef NB_MICRO_MAX
pstSoundPar=&stSoundPar;
#else
pstSoundPar=SND_fn_pCreateSoundParam(par->iNbLinks);
#endif
memcpy(pstSoundPar,par,SND_M_lGetSizeOfSoundParam(par));
pstThemeRes=&(theme_res.pstPtr->uRes.stTheme);
if (theme->bActive)
{/*------------transition theme à theme*/
if (change_theme(theme,theme_res))
{/*fade transition*/
NextRes=SND_fn_tduGetLowestResourceSnd(theme->uNextRes,theme->pstParam,TRUE);
SND_fn_bDoTransitionWithFadeSnd(theme->lVoice,NextRes);
}
else
{/*end-of-part transition*/
NextRes=SND_fn_tduGetLowestResourceSnd(theme->uNextRes,theme->pstParam,TRUE);
SND_fn_bSetNextTransitionSnd(theme->lVoice,NextRes);
}
}
else
{/*------------debut d'un theme (aucun theme actif avant)*/
start_new_theme(theme,theme_res);
theme->pbValid=valid;
theme->pfnFctCallback=fn_callback;
theme->lParCallback=par_callback;
/*---lancer la 1° part*/
/*part params are modified by Theme static params*/
pstSoundPar->ucVol=(unsigned char)(((long)pstSoundPar->ucVol*theme_res.pstPtr->ucVolume)>>7);
pstSoundPar->iFlags|=C_SOUNDPARAM_COEF_VOL;
FirstRes=SND_fn_tduGetLowestResourceSnd(theme->hCurrentPart->uRes,pstSoundPar,TRUE);
NextRes=SND_fn_tduGetLowestResourceSnd(theme->uNextRes,pstSoundPar,TRUE);
theme->lVoice=SND_fn_lPlayTransitionSnd(FirstRes,NextRes,fn_Transition,(long)theme,pstSoundPar);
}/*if (theme->bActive)*/
if (!theme->bActive)
{
if (theme->lVoice!=C_PLAY_FAILED)
{
theme->bActive=TRUE;
*valid=TRUE;
}
else
*valid=FALSE;
}
#ifndef NB_MICRO_MAX
SND_fn_vDestroySoundParam(pstSoundPar);
#endif
g_bWorkingTheme=FALSE;
if (theme->bActive)
return (long)theme;
else
#endif
return C_PLAY_FAILED;
}
SndBool SND_CALL SND_fn_bSetParamTheme(long canal,SoundParam* par)
{
#ifndef DISABLE_THEME
SoundParam *pstSoundPar;
active_theme *pTheme;
#ifdef NB_MICRO_MAX
SoundParam stSoundPar;
#endif
pTheme=(active_theme*)canal;
/*raj soundparam*/
raj_soundparam_theme(pTheme,par);
#ifdef NB_MICRO_MAX
pstSoundPar=&stSoundPar;
#else
pstSoundPar=SND_fn_pCreateSoundParam(par->iNbLinks);
#endif
memcpy(pstSoundPar,par,SND_M_lGetSizeOfSoundParam(par));
/*part params are modified by Theme static params*/
pstSoundPar->ucVol=(unsigned char)(((long)pstSoundPar->ucVol*pTheme->uCurrentThemeRes.pstPtr->ucVolume)>>7);
SND_fn_bSetParamTransitionSnd(pTheme->lVoice,pstSoundPar);
#ifndef NB_MICRO_MAX
SND_fn_vDestroySoundParam(pstSoundPar);
#endif
return pTheme->bActive;
#else
return FALSE;
#endif
}
SndBool SND_CALL SND_fn_bTestIsPlayingTheme(long canal)
{
#ifndef DISABLE_THEME
active_theme *pTheme;
pTheme=(active_theme*)canal;
return pTheme->bActive;
#else
return FALSE;
#endif
}
SndBool SND_CALL SND_fn_bAnyPlayingTheme()
{
#ifndef DISABLE_THEME
return g_stTheme.bActive;
#else
return FALSE;
#endif
}
void SND_CALL SND_fn_vStopTheme(long canal)
{
#ifndef DISABLE_THEME
active_theme *pTheme;
pTheme=(active_theme*)canal;
g_bWorkingTheme=TRUE;
if (pTheme->bActive)
SND_fn_vStopTransitionSnd(pTheme->lVoice);
if (pTheme->pfnFctCallback)
(*pTheme->pfnFctCallback)(pTheme->lParCallback);
pTheme->bActive=FALSE;
g_bWorkingTheme=FALSE;
#endif
}
void SND_CALL SND_fn_vPauseTheme(long canal)
{
#ifndef DISABLE_THEME
active_theme *pTheme;
pTheme=(active_theme*)canal;
if (pTheme->bActive)
SND_fn_vPauseTransitionSnd(pTheme->lVoice);
#endif
}
void SND_CALL SND_fn_vResumeTheme(long canal)
{
#ifndef DISABLE_THEME
active_theme *pTheme;
pTheme=(active_theme*)canal;
if (pTheme->bActive)
SND_fn_vResumeTransitionSnd(pTheme->lVoice);
#endif
}
void SND_fn_vRemoveCallbackTheme(long canal)
{
}
/*---------------------------------------------------------*/
/* GetPos: retourne la position "theorique" de la ressource*/
/* exprime en seconde depuis le debut*/
/* different du temps absolu (car pitch, derive..)*/
/* Entree: voie concernee*/
/* Sortie: temps en S (SndReal)*/
/*----------------------------------------------------------*/
SndReal SND_CALL SND_fn_rGetPosTheme(long voie)
{
return SND_C_POS_UNKNOWN;
}
/*---------------------------------------------------------*/
/* GetLength: retourne la duree "theorique" de la ressource*/
/* exprime en seconde (constant pour une ressource donnee)*/
/* Entree: voie concernee*/
/* Sortie: duree en S (SndReal)*/
/*----------------------------------------------------------*/
SndReal SND_CALL SND_fn_rGetLengthTheme(long voie)
{
return SND_C_POS_UNKNOWN;
}
SndBool SND_fn_bSetResourceStaticVolumeTheme(tdstBlockResourceMem* pstRes,unsigned char ucVolume)
{
pstRes->ucVolume=ucVolume;
return TRUE;
}
#endif
/* NO_ACP_SOUND*/