void Projectile::CreateAnimations(Animation **anims, const ieResRef bamres, int Seq) { AnimationFactory* af = ( AnimationFactory* ) gamedata->GetFactoryResource( bamres, IE_BAM_CLASS_ID, IE_NORMAL ); if (!af) { return; } int Max = af->GetCycleCount(); if (!Max) { return; } if((ExtFlags&PEF_CYCLE) && !Seq) { Seq=rand()%Max; } //this hack is needed because bioware .pro files are sometimes //reporting bigger face count than possible by the animation if (Aim>Max) Aim=Max; if(ExtFlags&PEF_PILLAR) { CreateCompositeAnimation(anims, af, Seq); } else { CreateOrientedAnimations(anims, af, Seq); } }
Font* BAMFontManager::GetFont(ieWord FirstChar, ieWord LastChar, unsigned short /*ptSize*/, FontStyle /*style*/, Palette* pal) { AnimationFactory* af = bamImp->GetAnimationFactory("dummy"); // FIXME: how does this get released? unsigned int i = 0, glyphIndexOffset = 0, limit = 0, Count = 0, glyphCount = 0; unsigned int CyclesCount = af->GetCycleCount(); // Numeric fonts have all frames in single cycle if (CyclesCount > 1) { Count = CyclesCount; glyphCount = (LastChar - FirstChar + 1); if (Count < glyphCount){ LastChar = LastChar - (glyphCount - Count); glyphCount = Count; } i = (FirstChar) ? FirstChar - 1 : FirstChar; limit = (FirstChar) ? LastChar - 1 : LastChar; glyphIndexOffset = i; } else { //numeric font Count = af->GetFrameCount(); glyphCount = Count; if (FirstChar+Count != (unsigned int) LastChar+1) { Log(ERROR, "BAMFontManager", "inconsistent font %s: FirstChar=%d LastChar=%d Count=%d", str->filename, FirstChar, LastChar, Count); return NULL; } limit = glyphCount - 1; } Sprite2D** glyphs = (Sprite2D**)malloc( glyphCount * sizeof(Sprite2D*) ); for (; i <= limit; i++) { if (CyclesCount > 1) { glyphs[i - glyphIndexOffset] = af->GetFrame(0, i); // Hack to work around original data where some status icons have inverted x and y positions (ie level up icon) // isStateFont is set in Open() and simply compares the first 6 characters of the file with "STATES" if (isStateFont) { // since initials and state icons should all be the same size/position we can just take the position of the first one glyphs[i - glyphIndexOffset]->YPos = glyphs[0]->YPos; } } else { glyphs[i - glyphIndexOffset] = af->GetFrameWithoutCycle(i); glyphs[i - glyphIndexOffset]->YPos = 13 - glyphs[i - glyphIndexOffset]->Height; } } // assume all sprites have same palette Palette* palette = glyphs[0]->GetPalette(); Font* fnt = new Font(glyphs, FirstChar, LastChar, palette); palette->Release(); if (pal) { fnt->SetPalette(pal); } return fnt; }
/* Creating animation from VVC */ ScriptedAnimation::ScriptedAnimation(DataStream* stream) { Init(); if (!stream) { return; } char Signature[8]; stream->Read( Signature, 8); if (strncmp( Signature, "VVC V1.0", 8 ) != 0) { print("Not a valid VVC File"); delete stream; return; } ieResRef Anim1ResRef; ieDword seq1, seq2, seq3; stream->ReadResRef( Anim1ResRef ); //there is no proof it is a second resref //stream->ReadResRef( Anim2ResRef ); stream->Seek( 8, GEM_CURRENT_POS ); stream->ReadDword( &Transparency ); stream->Seek( 4, GEM_CURRENT_POS ); stream->ReadDword( &SequenceFlags ); stream->Seek( 4, GEM_CURRENT_POS ); ieDword tmp; stream->ReadDword( &tmp ); XPos = (signed) tmp; stream->ReadDword( &tmp ); //this affects visibility ZPos = (signed) tmp; stream->Seek( 4, GEM_CURRENT_POS ); stream->ReadDword( &FrameRate ); if (!FrameRate) FrameRate = DEFAULT_FRAMERATE; stream->ReadDword( &FaceTarget ); stream->Seek( 16, GEM_CURRENT_POS ); stream->ReadDword( &tmp ); //this doesn't affect visibility YPos = (signed) tmp; stream->ReadDword( &LightX ); stream->ReadDword( &LightY ); stream->ReadDword( &LightZ ); stream->ReadDword( &Duration ); stream->Seek( 8, GEM_CURRENT_POS ); stream->ReadDword( &seq1 ); if (seq1>0) seq1--; //hack but apparently it works this way stream->ReadDword( &seq2 ); stream->Seek( 8, GEM_CURRENT_POS ); stream->ReadResRef( sounds[P_ONSET] ); stream->ReadResRef( sounds[P_HOLD] ); stream->Seek( 8, GEM_CURRENT_POS ); stream->ReadDword( &seq3 ); stream->ReadResRef( sounds[P_RELEASE] ); //if there are no separate phases, then fill the p_hold fields bool phases = (seq2 || seq3); // hacks for seq2/seq3, same as for seq1 above // (not sure if seq3 is needed) if (seq2>0) seq2--; if (seq3>0) seq3--; if (SequenceFlags&IE_VVC_BAM) { AnimationFactory* af = ( AnimationFactory* ) gamedata->GetFactoryResource( Anim1ResRef, IE_BAM_CLASS_ID ); //no idea about vvc phases, i think they got no endphase? //they certainly got onset and hold phases //the face target flag should be handled too for (int i=0;i<MAX_ORIENT;i++) { unsigned int p_hold = P_HOLD*MAX_ORIENT+i; unsigned int p_onset = P_ONSET*MAX_ORIENT+i; unsigned int p_release = P_RELEASE*MAX_ORIENT+i; int c = seq1; if (phases) { switch (FaceTarget) { case 5: c=SixteenToFive[i]; break; case 9: c=SixteenToNine[i]; break; case 16: //this is an uglybugly hack, i still have to //figure out what 'FaceTarget' really is if ( (int) af->GetCycleCount()>i) c=i; break; } anims[p_onset] = af->GetCycle( c ); if (anims[p_onset]) { PrepareAnimation(anims[p_onset], Transparency); //creature anims may start at random position, vvcs always start on 0 anims[p_onset]->pos=0; //vvcs are always paused anims[p_onset]->gameAnimation=true; anims[p_onset]->Flags |= S_ANI_PLAYONCE; } } c = phases ? seq2 : seq1; if (c || !phases) { switch (FaceTarget) { case 5: c=SixteenToFive[i]; break; case 9: c=SixteenToNine[i]; break; case 16: //this is an uglybugly hack, i still have to //figure out what 'FaceTarget' really is if ((int) af->GetCycleCount()>i) c=i; break; } anims[p_hold] = af->GetCycle( c ); if (anims[p_hold]) { PrepareAnimation(anims[p_hold], Transparency); anims[p_hold]->pos=0; anims[p_hold]->gameAnimation=true; if (!(SequenceFlags&IE_VVC_LOOP) ) { anims[p_hold]->Flags |= S_ANI_PLAYONCE; } } } c = seq3; if (c) { switch (FaceTarget) { case 5: c=SixteenToFive[i]; break; case 9: c=SixteenToNine[i]; break; case 16: //this is an uglybugly hack, i still have to //figure out what 'FaceTarget' really is if ( (int) af->GetCycleCount()>i) c=i; break; } anims[p_release] = af->GetCycle( ( unsigned char ) c ); if (anims[p_release]) { PrepareAnimation(anims[p_release], Transparency); anims[p_release]->pos=0; anims[p_release]->gameAnimation=true; anims[p_release]->Flags |= S_ANI_PLAYONCE; } } } PreparePalette(); } SetPhase(P_ONSET); delete stream; }