931 lines
27 KiB
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*/
|
|
|
|
|