From 6a37636bb020273d1a0e7115e5fe2ce7d2905454 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Tue, 10 Jan 2012 23:43:54 +0000 Subject: [PATCH] Possibility of specifying sounds for a VPX anim-replacement via DEF. The syntax is as follows: animsounds { frame1 sound1 frame2 sound2 ... } has to be one of the tokens: cineov2, cineov3, RADLOGO, DUKETEAM, logo, vol41a, vol42a, vol4e1, vol43a, vol4e2, or vol4e3, corresponding to hard-coded Duke3D anims. The frameN's (1-based frame numbers) have to be in ascending order (but not necessarily strictly ascending, so that a frame may have more than one sound). Example: for Duke3D's XBLA nuke logo animation (IVF extracted from nuke.webm), the following definition overlays the video with a sound sequence similar (identical save for timing) to the original nuke animation: // frame 1: FLY_BY, frame 64: PIPEBOMB_EXPLODE animsounds logo { 1 244 64 14 } git-svn-id: https://svn.eduke32.com/eduke32@2242 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/src/defs.c | 25 +++++- polymer/eduke32/source/anim.c | 50 +++++++++--- polymer/eduke32/source/anim.h | 8 ++ polymer/eduke32/source/game.c | 128 +++++++++++++++++++++++++++++++ 4 files changed, 200 insertions(+), 11 deletions(-) diff --git a/polymer/eduke32/build/src/defs.c b/polymer/eduke32/build/src/defs.c index 972911897..5e2378715 100644 --- a/polymer/eduke32/build/src/defs.c +++ b/polymer/eduke32/build/src/defs.c @@ -81,7 +81,8 @@ enum scripttoken_t T_IMPORTTILE, T_MUSIC,T_ID,T_SOUND, T_TILEFROMTEXTURE, T_XOFFSET, T_YOFFSET, - T_INCLUDEDEFAULT + T_INCLUDEDEFAULT, + T_ANIMSOUNDS, }; typedef struct { const char *text; int32_t tokenid; } tokenlist; @@ -175,7 +176,9 @@ static int32_t defsparser(scriptfile *script) { "tile", T_TEXTURE }, { "music", T_MUSIC }, { "sound", T_SOUND }, - +#ifdef USE_LIBVPX + { "animsounds", T_ANIMSOUNDS }, // dummy +#endif // other stuff { "undefmodel", T_UNDEFMODEL }, { "undefmodelrange", T_UNDEFMODELRANGE }, @@ -1958,6 +1961,24 @@ static int32_t defsparser(scriptfile *script) } break; +#ifdef USE_LIBVPX + case T_ANIMSOUNDS: + { + char *dummy; + + static const tokenlist dummytokens[] = { { "id", T_ID }, }; + + if (scriptfile_getstring(script, &dummy)) break; + if (scriptfile_getbraces(script,&dummy)) break; + while (script->textptr < dummy) + { + // XXX? + getatoken(script,dummytokens,sizeof(dummytokens)/sizeof(dummytokens)); + } + } + break; +#endif + case T_SOUND: case T_MUSIC: { diff --git a/polymer/eduke32/source/anim.c b/polymer/eduke32/source/anim.c index 479a1dc65..3bddf4476 100644 --- a/polymer/eduke32/source/anim.c +++ b/polymer/eduke32/source/anim.c @@ -25,11 +25,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mouse.h" #include "compat.h" +#include "anim.h" + #ifdef USE_LIBVPX # include "animvpx.h" + +uint16_t anim_hi_numsounds[NUM_HARDCODED_ANIMS], *anim_hi_sounds[NUM_HARDCODED_ANIMS]; #endif -void endanimsounds(int32_t fr) +static void endanimsounds(int32_t fr) { switch (ud.volume_number) { @@ -94,7 +98,7 @@ void endanimsounds(int32_t fr) } } -void logoanimsounds(int32_t fr) +static void logoanimsounds(int32_t fr) { switch (fr) { @@ -107,7 +111,7 @@ void logoanimsounds(int32_t fr) } } -void intro4animsounds(int32_t fr) +static void intro4animsounds(int32_t fr) { switch (fr) { @@ -124,7 +128,7 @@ void intro4animsounds(int32_t fr) } } -void first4animsounds(int32_t fr) +static void first4animsounds(int32_t fr) { switch (fr) { @@ -143,7 +147,7 @@ void first4animsounds(int32_t fr) } } -void intro42animsounds(int32_t fr) +static void intro42animsounds(int32_t fr) { switch (fr) { @@ -153,7 +157,7 @@ void intro42animsounds(int32_t fr) } } -void endanimvol41(int32_t fr) +static void endanimvol41(int32_t fr) { switch (fr) { @@ -166,7 +170,7 @@ void endanimvol41(int32_t fr) } } -void endanimvol42(int32_t fr) +static void endanimvol42(int32_t fr) { switch (fr) { @@ -185,7 +189,7 @@ void endanimvol42(int32_t fr) } } -void endanimvol43(int32_t fr) +static void endanimvol43(int32_t fr) { switch (fr) { @@ -212,7 +216,19 @@ void G_PlayAnim(const char *fn,char t) int32_t handle=-1; int32_t frametime = 0; - // return; + // t parameter: + // + // 1: cineov2 + // 2: cineov3 + // 3: RADLOGO + // 4: DUKETEAM + // 5: logo + // 6: vol41a + // 7: vol42a + // 8: vol4e1 + // 9: vol43a + // 10: vol4e2 + // 11: vol4e3 if (t != 7 && t != 9 && t != 10 && t != 11) KB_FlushKeyboardQueue(); @@ -233,6 +249,7 @@ void G_PlayAnim(const char *fn,char t) uint8_t *pic; uint32_t msecsperframe, nextframetime; int32_t running = 1; + int32_t animidx, framenum=0, soundidx=0, numtotalsounds=0; // custom anim sounds Bstrncpy(vpxfn, fn, BMAX_PATH); vpxfn[BMAX_PATH-1] = 0; @@ -266,6 +283,10 @@ void G_PlayAnim(const char *fn,char t) break; } + animidx = t-1; + if ((unsigned)animidx < NUM_HARDCODED_ANIMS && anim_hi_sounds[animidx]) + numtotalsounds = anim_hi_numsounds[animidx]; + msecsperframe = ((uint64_t)info.fpsdenom*1000)/info.fpsnumer; // OSD_Printf("msecs per frame: %d\n", msecsperframe); @@ -294,6 +315,17 @@ void G_PlayAnim(const char *fn,char t) animvpx_render_frame(&codec); + // after rendering the frame but before displaying: maybe play sound... + framenum++; + if (soundidx < numtotalsounds) + { + if (anim_hi_sounds[animidx][2*soundidx] == framenum) + { + S_PlaySound(anim_hi_sounds[animidx][2*soundidx+1]); + soundidx++; + } + } + // this and showframe() instead of nextpage() are so that // nobody tramples on our carefully set up GL state! palfadedelta = 0; diff --git a/polymer/eduke32/source/anim.h b/polymer/eduke32/source/anim.h index 6e68be0e9..a496464fd 100644 --- a/polymer/eduke32/source/anim.h +++ b/polymer/eduke32/source/anim.h @@ -23,7 +23,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __anim_h__ #define __anim_h__ +#define NUM_HARDCODED_ANIMS 11 + +# ifdef USE_LIBVPX +extern uint16_t anim_hi_numsounds[NUM_HARDCODED_ANIMS], *anim_hi_sounds[NUM_HARDCODED_ANIMS]; +# endif + void G_PlayAnim(const char *fn,char t); +/* void endanimvol43(int32_t fr); void endanimvol42(int32_t fr); void endanimvol41(int32_t fr); @@ -32,4 +39,5 @@ void first4animsounds(int32_t fr); void intro4animsounds(int32_t fr); void logoanimsounds(int32_t fr); void endanimsounds(int32_t fr); +*/ #endif diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index e89208f48..e2e2256bc 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -226,6 +226,7 @@ enum gametokens T_MUSIC, T_SOUND, T_FILE, + T_ANIMSOUNDS, T_ID }; @@ -8205,6 +8206,9 @@ static int32_t parsedefinitions_game(scriptfile *script, const int32_t preload) { "noautoload", T_NOAUTOLOAD }, { "music", T_MUSIC }, { "sound", T_SOUND }, +#ifdef USE_LIBVPX + { "animsounds", T_ANIMSOUNDS }, +#endif }; static const tokenlist sound_musictokens[] = @@ -8317,6 +8321,130 @@ static int32_t parsedefinitions_game(scriptfile *script, const int32_t preload) } break; +#ifdef USE_LIBVPX + case T_ANIMSOUNDS: + { + char *otokptr = script->ltextptr; + char *animsoundsend = NULL; + int32_t animnum, numpairs=0, allocsz=4, bad, lastframenum=INT32_MIN; + + static const tokenlist hardcoded_anim_tokens[] = + { + { "cineov2", 0 }, + { "cineov3", 1 }, + { "RADLOGO", 2 }, + { "DUKETEAM", 3 }, + { "logo", 4 }, + { "vol41a", 5 }, + { "vol42a", 6 }, + { "vol4e1", 7 }, + { "vol43a", 8 }, + { "vol4e2", 9 }, + { "vol4e3", 10 }, + // NUM_HARDCODED_ANIMS + }; + + animnum = getatoken(script, hardcoded_anim_tokens, NUM_HARDCODED_ANIMS); + if ((unsigned)animnum >= NUM_HARDCODED_ANIMS) + initprintf("Error: expected a hardcoded anim file name (sans extension) on line %s:%d\n", + script->filename, scriptfile_getlinum(script, otokptr)); + + if (scriptfile_getbraces(script, &animsoundsend)) break; + + if (anim_hi_sounds[animnum]) + { + initprintf("Warning: overwriting already defined hi-anim %s's sounds on line %s:%d\n", + hardcoded_anim_tokens[animnum].text, script->filename, + scriptfile_getlinum(script, otokptr)); + Bfree(anim_hi_sounds[animnum]); + anim_hi_numsounds[animnum] = 0; + } + + if (!preload) + anim_hi_sounds[animnum] = Bcalloc(allocsz, 2*sizeof(anim_hi_sounds[0])); + while (script->textptr < animsoundsend) + { + int32_t framenum, soundnum; + + if (preload) + { + // dummy + getatoken(script, hardcoded_anim_tokens, NUM_HARDCODED_ANIMS); + continue; + } + + // XXX: ugly, will produce error when it encounters the closing '}' + if (scriptfile_getnumber(script, &framenum)) break; + + bad=1; + + if (anim_hi_sounds[animnum]==NULL) // Bcalloc check + break; + + if (scriptfile_getsymbol(script, &soundnum)) break; + + // frame numbers start at 1 for us + if (framenum <= 0) + { + initprintf("Error: frame number must be greater zero on line %s:%d\n", + script->filename, scriptfile_getlinum(script, script->ltextptr)); + break; + } + + if (framenum < lastframenum) + { + initprintf("Error: frame numbers must be in (not necessarily strictly)" + " ascending order (line %s:%d)\n", + script->filename, scriptfile_getlinum(script, script->ltextptr)); + break; + } + lastframenum = framenum; + + if ((unsigned)soundnum >= MAXSOUNDS) + { + initprintf("Error: sound number #%d invalid on line %s:%d\n", soundnum, + script->filename, scriptfile_getlinum(script, script->ltextptr)); + break; + } + + if (numpairs >= allocsz) + { + void *newptr; + + allocsz *= 2; + newptr = Brealloc(anim_hi_sounds[animnum], allocsz*2*sizeof(anim_hi_sounds[0])); + + if (!newptr) break; + anim_hi_sounds[animnum] = newptr; + } + + bad=0; + + anim_hi_sounds[animnum][2*numpairs] = framenum; + anim_hi_sounds[animnum][2*numpairs+1] = soundnum; + numpairs++; + } + + if (!preload) + { + if (!bad) + { + anim_hi_numsounds[animnum] = numpairs; + initprintf("Defined sound sequence for hi-anim '%s' with %d frame/sound pairs\n", + hardcoded_anim_tokens[animnum].text, numpairs); + } + else + { + Bfree(anim_hi_sounds[animnum]); + anim_hi_sounds[animnum] = NULL; + initprintf("Failed defining sound sequence for hi-anim '%s'.\n", + hardcoded_anim_tokens[animnum].text); + } + } + } + break; +#endif // defined USE_LIBVPX + case T_SOUND: { char *tinttokptr = script->ltextptr;