- allow oscillating for discretely defined animations as well, not just for ranged ones.

- add random animations.
This commit is contained in:
Christoph Oelckers 2015-03-21 12:48:37 +01:00
parent 502120e78f
commit ffbcda206c
2 changed files with 61 additions and 33 deletions

View file

@ -68,7 +68,7 @@ static FRandom pr_animatepictures ("AnimatePics");
// //
//========================================================================== //==========================================================================
void FTextureManager::AddAnim (FAnimDef *anim) FAnimDef *FTextureManager::AddAnim (FAnimDef *anim)
{ {
// Search for existing duplicate. // Search for existing duplicate.
for (unsigned int i = 0; i < mAnimations.Size(); ++i) for (unsigned int i = 0; i < mAnimations.Size(); ++i)
@ -78,11 +78,12 @@ void FTextureManager::AddAnim (FAnimDef *anim)
// Found one! // Found one!
free (mAnimations[i]); free (mAnimations[i]);
mAnimations[i] = anim; mAnimations[i] = anim;
return; return anim;
} }
} }
// Didn't find one, so add it at the end. // Didn't find one, so add it at the end.
mAnimations.Push (anim); mAnimations.Push (anim);
return anim;
} }
//========================================================================== //==========================================================================
@ -94,7 +95,7 @@ void FTextureManager::AddAnim (FAnimDef *anim)
// //
//========================================================================== //==========================================================================
void FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD speedmin, DWORD speedrange) FAnimDef *FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, DWORD speedmin, DWORD speedrange)
{ {
if (AreTexturesCompatible(picnum, picnum + (animcount - 1))) if (AreTexturesCompatible(picnum, picnum + (animcount - 1)))
{ {
@ -102,13 +103,15 @@ void FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, int animt
anim->CurFrame = 0; anim->CurFrame = 0;
anim->BasePic = picnum; anim->BasePic = picnum;
anim->NumFrames = animcount; anim->NumFrames = animcount;
anim->AnimType = animtype; anim->AnimType = FAnimDef::ANIM_Forward;
anim->bDiscrete = false;
anim->SwitchTime = 0; anim->SwitchTime = 0;
anim->Frames[0].SpeedMin = speedmin; anim->Frames[0].SpeedMin = speedmin;
anim->Frames[0].SpeedRange = speedrange; anim->Frames[0].SpeedRange = speedrange;
anim->Frames[0].FramePic = anim->BasePic; anim->Frames[0].FramePic = anim->BasePic;
AddAnim (anim); return AddAnim (anim);
} }
return NULL;
} }
//========================================================================== //==========================================================================
@ -119,16 +122,17 @@ void FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, int animt
// //
//========================================================================== //==========================================================================
void FTextureManager::AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames) FAnimDef *FTextureManager::AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames)
{ {
FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1) * sizeof(frames[0])); FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1) * sizeof(frames[0]));
anim->BasePic = picnum; anim->BasePic = picnum;
anim->NumFrames = frames.Size(); anim->NumFrames = frames.Size();
anim->CurFrame = 0; anim->CurFrame = 0;
anim->AnimType = FAnimDef::ANIM_DiscreteFrames; anim->AnimType = FAnimDef::ANIM_Forward;
anim->bDiscrete = true;
anim->SwitchTime = 0; anim->SwitchTime = 0;
memcpy (&anim->Frames[0], &frames[0], frames.Size() * sizeof(frames[0])); memcpy (&anim->Frames[0], &frames[0], frames.Size() * sizeof(frames[0]));
AddAnim (anim); return AddAnim (anim);
} }
//========================================================================== //==========================================================================
@ -333,6 +337,8 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
FTextureID picnum; FTextureID picnum;
int defined = 0; int defined = 0;
bool optional = false, missing = false; bool optional = false, missing = false;
FAnimDef *ani = NULL;
BYTE type = FAnimDef::ANIM_Forward;
sc.MustGetString (); sc.MustGetString ();
if (sc.Compare ("optional")) if (sc.Compare ("optional"))
@ -370,6 +376,22 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
} }
continue; continue;
} }
else if (sc.Compare ("Oscillate"))
{
if (type == FAnimDef::ANIM_Random)
{
sc.ScriptError ("You cannot use \"random\" and \"oscillate\" together in a single animation.");
}
type = FAnimDef::ANIM_OscillateUp;
}
else if (sc.Compare("Random"))
{
if (type == FAnimDef::ANIM_OscillateUp)
{
sc.ScriptError ("You cannot use \"random\" and \"oscillate\" together in a single animation.");
}
type = FAnimDef::ANIM_Random;
}
else if (sc.Compare ("range")) else if (sc.Compare ("range"))
{ {
if (defined == 2) if (defined == 2)
@ -381,7 +403,7 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
sc.ScriptError ("You can only use one \"range\" per animation."); sc.ScriptError ("You can only use one \"range\" per animation.");
} }
defined = 1; defined = 1;
ParseRangeAnim (sc, picnum, usetype, missing); ani = ParseRangeAnim (sc, picnum, usetype, missing);
} }
else if (sc.Compare ("pic")) else if (sc.Compare ("pic"))
{ {
@ -407,7 +429,12 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
{ {
sc.ScriptError ("Animation needs at least 2 frames"); sc.ScriptError ("Animation needs at least 2 frames");
} }
AddComplexAnim (picnum, frames); ani = AddComplexAnim (picnum, frames);
}
if (ani != NULL && type != FAnimDef::ANIM_Forward)
{
if (ani->AnimType == FAnimDef::ANIM_Backward && type == FAnimDef::ANIM_OscillateUp) ani->AnimType = FAnimDef::ANIM_OscillateDown;
else ani->AnimType = type;
} }
} }
@ -420,7 +447,7 @@ void FTextureManager::ParseAnim (FScanner &sc, int usetype)
// //
//========================================================================== //==========================================================================
void FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing) FAnimDef *FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing)
{ {
int type; int type;
FTextureID framenum; FTextureID framenum;
@ -432,7 +459,7 @@ void FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usety
if (framenum == picnum || !picnum.Exists()) if (framenum == picnum || !picnum.Exists())
{ {
return; // Animation is only one frame or does not exist return NULL; // Animation is only one frame or does not exist
} }
if (framenum < picnum) if (framenum < picnum)
{ {
@ -440,18 +467,9 @@ void FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usety
Texture(framenum)->bNoDecals = Texture(picnum)->bNoDecals; Texture(framenum)->bNoDecals = Texture(picnum)->bNoDecals;
swapvalues (framenum, picnum); swapvalues (framenum, picnum);
} }
if (sc.GetString()) FAnimDef *ani = AddSimpleAnim (picnum, framenum - picnum + 1, min, max - min);
{ ani->AnimType = type;
if (sc.Compare ("Oscillate")) return ani;
{
type = type == FAnimDef::ANIM_Forward ? FAnimDef::ANIM_OscillateUp : FAnimDef::ANIM_OscillateDown;
}
else
{
sc.UnGet ();
}
}
AddSimpleAnim (picnum, framenum - picnum + 1, type, min, max - min);
} }
//========================================================================== //==========================================================================
@ -691,7 +709,7 @@ void FTextureManager::FixAnimations ()
for (i = 0; i < mAnimations.Size(); ++i) for (i = 0; i < mAnimations.Size(); ++i)
{ {
FAnimDef *anim = mAnimations[i]; FAnimDef *anim = mAnimations[i];
if (anim->AnimType == FAnimDef::ANIM_DiscreteFrames) if (anim->bDiscrete)
{ {
if (Texture(anim->BasePic)->bNoRemap0) if (Texture(anim->BasePic)->bNoRemap0)
{ {
@ -830,7 +848,7 @@ FDoorAnimation *FTextureManager::FindAnimatedDoor (FTextureID picnum)
void FAnimDef::SetSwitchTime (DWORD mstime) void FAnimDef::SetSwitchTime (DWORD mstime)
{ {
int speedframe = (AnimType == FAnimDef::ANIM_DiscreteFrames) ? CurFrame : 0; int speedframe = bDiscrete ? CurFrame : 0;
SwitchTime = mstime + Frames[speedframe].SpeedMin; SwitchTime = mstime + Frames[speedframe].SpeedMin;
if (Frames[speedframe].SpeedRange != 0) if (Frames[speedframe].SpeedRange != 0)
@ -889,7 +907,6 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
{ {
default: default:
case FAnimDef::ANIM_Forward: case FAnimDef::ANIM_Forward:
case FAnimDef::ANIM_DiscreteFrames:
anim->CurFrame = (anim->CurFrame + 1) % anim->NumFrames; anim->CurFrame = (anim->CurFrame + 1) % anim->NumFrames;
break; break;
@ -904,6 +921,16 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
} }
break; break;
case FAnimDef::ANIM_Random:
// select a random frame other than the current one
if (anim->NumFrames > 1)
{
WORD rndFrame = (WORD)pr_animatepictures(anim->NumFrames - 1);
if (rndFrame >= anim->CurFrame) rndFrame++;
anim->CurFrame = rndFrame;
}
break;
case FAnimDef::ANIM_OscillateUp: case FAnimDef::ANIM_OscillateUp:
anim->CurFrame = anim->CurFrame + 1; anim->CurFrame = anim->CurFrame + 1;
if (anim->CurFrame >= anim->NumFrames - 1) if (anim->CurFrame >= anim->NumFrames - 1)
@ -923,7 +950,7 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
anim->SetSwitchTime (mstime); anim->SetSwitchTime (mstime);
} }
if (anim->AnimType == FAnimDef::ANIM_DiscreteFrames) if (anim->bDiscrete)
{ {
SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic); SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic);
} }

View file

@ -64,6 +64,7 @@ struct FAnimDef
WORD NumFrames; WORD NumFrames;
WORD CurFrame; WORD CurFrame;
BYTE AnimType; BYTE AnimType;
bool bDiscrete; // taken out of AnimType to have better control
DWORD SwitchTime; // Time to advance to next frame DWORD SwitchTime; // Time to advance to next frame
struct FAnimFrame struct FAnimFrame
{ {
@ -77,7 +78,7 @@ struct FAnimDef
ANIM_Backward, ANIM_Backward,
ANIM_OscillateUp, ANIM_OscillateUp,
ANIM_OscillateDown, ANIM_OscillateDown,
ANIM_DiscreteFrames ANIM_Random
}; };
void SetSwitchTime (DWORD mstime); void SetSwitchTime (DWORD mstime);
@ -423,14 +424,14 @@ private:
void InitBuildTiles (); void InitBuildTiles ();
// Animation stuff // Animation stuff
void AddAnim (FAnimDef *anim); FAnimDef *AddAnim (FAnimDef *anim);
void FixAnimations (); void FixAnimations ();
void InitAnimated (); void InitAnimated ();
void InitAnimDefs (); void InitAnimDefs ();
void AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD speedmin, DWORD speedrange=0); FAnimDef *AddSimpleAnim (FTextureID picnum, int animcount, DWORD speedmin, DWORD speedrange=0);
void AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames); FAnimDef *AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames);
void ParseAnim (FScanner &sc, int usetype); void ParseAnim (FScanner &sc, int usetype);
void ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing); FAnimDef *ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing);
void ParsePicAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames); void ParsePicAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames);
void ParseWarp(FScanner &sc); void ParseWarp(FScanner &sc);
void ParseCameraTexture(FScanner &sc); void ParseCameraTexture(FScanner &sc);