- Texture animation improvements:
* Animations are now millisecond-accurate, so delays in ANIMDEFS can have
fractional parts.
* Cleaned up the animation code and moved it into r_anim.cpp.
* Blood's oscillating texture animations are now available for use by actual
supported games by adding the word "oscillate" after a "range" definition
in ANIMDEFS.
* Not exactly texture animation, but it's handled in the same function as
texture animations: Scrolling skies also have millisecond precision.
SVN r125 (trunk)
This commit is contained in:
parent
3f51b80cac
commit
6863938e67
10 changed files with 826 additions and 648 deletions
629
src/p_spec.cpp
629
src/p_spec.cpp
|
|
@ -68,7 +68,6 @@
|
|||
#include "r_sky.h"
|
||||
|
||||
static FRandom pr_playerinspecialsector ("PlayerInSpecialSector");
|
||||
static FRandom pr_animatepictures ("AnimatePics");
|
||||
|
||||
// [GrafZahl] Make this message changable by the user! ;)
|
||||
CVAR(String, secretmessage, "A Secret is revealed!", CVAR_ARCHIVE)
|
||||
|
|
@ -113,563 +112,11 @@ void DPusher::Serialize (FArchive &arc)
|
|||
<< m_Affectee;
|
||||
}
|
||||
|
||||
//
|
||||
// Animating textures and planes
|
||||
//
|
||||
// [RH] Expanded to work with a Hexen ANIMDEFS lump
|
||||
//
|
||||
|
||||
struct FAnimDef
|
||||
{
|
||||
WORD BasePic;
|
||||
WORD NumFrames;
|
||||
WORD CurFrame;
|
||||
BYTE bUniqueFrames:1;
|
||||
BYTE AnimType:2;
|
||||
BYTE Countdown;
|
||||
struct FAnimFrame
|
||||
{
|
||||
BYTE SpeedMin;
|
||||
BYTE SpeedRange;
|
||||
WORD FramePic;
|
||||
} Frames[1];
|
||||
enum
|
||||
{
|
||||
ANIM_Forward,
|
||||
ANIM_Backward,
|
||||
ANIM_OscillateUp,
|
||||
ANIM_OscillateDown,
|
||||
};
|
||||
};
|
||||
|
||||
class DeletingAnimArray : public TArray<FAnimDef *>
|
||||
{
|
||||
public:
|
||||
~DeletingAnimArray()
|
||||
{
|
||||
for(unsigned i=0;i<Size();i++)
|
||||
{
|
||||
if ((*this)[i] != NULL) free((*this)[i]);
|
||||
(*this)[i]=NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
static DeletingAnimArray Anims;
|
||||
|
||||
// killough 3/7/98: Initialize generalized scrolling
|
||||
static void P_SpawnScrollers();
|
||||
|
||||
static void P_FixAnimations ();
|
||||
|
||||
static void P_SpawnFriction (); // phares 3/16/98
|
||||
static void P_SpawnPushers (); // phares 3/20/98
|
||||
|
||||
static void ParseAnim (bool istex);
|
||||
|
||||
//
|
||||
// Animating line specials
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// [RH] P_InitAnimDefs
|
||||
//
|
||||
// This uses a Hexen ANIMDEFS lump to define the animation sequences
|
||||
//
|
||||
static void P_InitAnimDefs ()
|
||||
{
|
||||
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
|
||||
int lump, lastlump = 0;
|
||||
|
||||
while ((lump = Wads.FindLump ("ANIMDEFS", &lastlump)) != -1)
|
||||
{
|
||||
SC_OpenLumpNum (lump, "ANIMDEFS");
|
||||
|
||||
while (SC_GetString ())
|
||||
{
|
||||
if (SC_Compare ("flat"))
|
||||
{
|
||||
ParseAnim (false);
|
||||
}
|
||||
else if (SC_Compare ("texture"))
|
||||
{
|
||||
ParseAnim (true);
|
||||
}
|
||||
else if (SC_Compare ("switch"))
|
||||
{
|
||||
P_ProcessSwitchDef ();
|
||||
}
|
||||
// [GRB] Added warping type 2
|
||||
else if (SC_Compare ("warp") || SC_Compare ("warp2"))
|
||||
{
|
||||
bool isflat = false;
|
||||
BOOL type2 = SC_Compare ("warp2"); // [GRB]
|
||||
SC_MustGetString ();
|
||||
if (SC_Compare ("flat"))
|
||||
{
|
||||
isflat = true;
|
||||
SC_MustGetString ();
|
||||
}
|
||||
else if (SC_Compare ("texture"))
|
||||
{
|
||||
isflat = false;
|
||||
SC_MustGetString ();
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_ScriptError (NULL);
|
||||
}
|
||||
int picnum = TexMan.CheckForTexture (sc_String, isflat ? FTexture::TEX_Flat : FTexture::TEX_Wall, texflags);
|
||||
if (picnum != -1)
|
||||
{
|
||||
FTexture * warper = TexMan[picnum];
|
||||
|
||||
// don't warp a texture more than once
|
||||
if (!warper->bWarped)
|
||||
{
|
||||
if (type2) // [GRB]
|
||||
warper = new FWarp2Texture (warper);
|
||||
else
|
||||
warper = new FWarpTexture (warper);
|
||||
TexMan.ReplaceTexture (picnum, warper, false);
|
||||
}
|
||||
|
||||
// No decals on warping textures, by default.
|
||||
// Warping information is taken from the last warp
|
||||
// definition for this texture.
|
||||
warper->bNoDecals = true;
|
||||
if (SC_GetString ())
|
||||
{
|
||||
if (SC_Compare ("allowdecals"))
|
||||
{
|
||||
warper->bNoDecals = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_UnGet ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SC_Compare ("cameratexture"))
|
||||
{
|
||||
int width, height;
|
||||
int fitwidth, fitheight;
|
||||
char *picname;
|
||||
|
||||
SC_MustGetString ();
|
||||
picname = copystring (sc_String);
|
||||
SC_MustGetNumber ();
|
||||
width = sc_Number;
|
||||
SC_MustGetNumber ();
|
||||
height = sc_Number;
|
||||
int picnum = TexMan.CheckForTexture (picname, FTexture::TEX_Flat, texflags);
|
||||
FTexture *viewer = new FCanvasTexture (picname, width, height);
|
||||
if (picnum != -1)
|
||||
{
|
||||
FTexture *oldtex = TexMan[picnum];
|
||||
fitwidth = DivScale3 (oldtex->GetWidth (), oldtex->ScaleX ? oldtex->ScaleX : 8);
|
||||
fitheight = DivScale3 (oldtex->GetHeight (), oldtex->ScaleY ? oldtex->ScaleY : 8);
|
||||
viewer->UseType = oldtex->UseType;
|
||||
TexMan.ReplaceTexture (picnum, viewer, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
fitwidth = width;
|
||||
fitheight = height;
|
||||
// [GRB] No need for oldtex
|
||||
viewer->UseType = FTexture::TEX_Wall;
|
||||
TexMan.AddTexture (viewer);
|
||||
}
|
||||
delete[] picname;
|
||||
if (SC_GetString())
|
||||
{
|
||||
if (SC_Compare ("fit"))
|
||||
{
|
||||
SC_MustGetNumber ();
|
||||
fitwidth = sc_Number;
|
||||
SC_MustGetNumber ();
|
||||
fitheight = sc_Number;
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_UnGet ();
|
||||
}
|
||||
}
|
||||
viewer->ScaleX = width * 8 / fitwidth;
|
||||
viewer->ScaleY = height * 8 / fitheight;
|
||||
}
|
||||
else if (SC_Compare ("animatedDoor"))
|
||||
{
|
||||
P_ParseAnimatedDoor ();
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_ScriptError (NULL);
|
||||
}
|
||||
}
|
||||
SC_Close ();
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseAnim (bool istex)
|
||||
{
|
||||
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
|
||||
TArray<FAnimDef::FAnimFrame> frames (32);
|
||||
FAnimDef::FAnimFrame frame;
|
||||
FAnimDef sink;
|
||||
FAnimDef *newAnim;
|
||||
int picnum;
|
||||
int framenum;
|
||||
int min, max;
|
||||
unsigned int i;
|
||||
bool optional = false, missing = false;
|
||||
|
||||
SC_MustGetString ();
|
||||
if (SC_Compare ("optional"))
|
||||
{
|
||||
optional = true;
|
||||
SC_MustGetString ();
|
||||
}
|
||||
picnum = TexMan.CheckForTexture (sc_String, istex ? FTexture::TEX_Wall : FTexture::TEX_Flat, texflags);
|
||||
|
||||
if (picnum < 0)
|
||||
{
|
||||
if (optional)
|
||||
{
|
||||
missing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf (PRINT_BOLD, "ANIMDEFS: Can't find %s\n", sc_String);
|
||||
}
|
||||
}
|
||||
|
||||
sink.CurFrame = 0;
|
||||
sink.BasePic = picnum;
|
||||
sink.bUniqueFrames = true;
|
||||
sink.AnimType = FAnimDef::ANIM_Forward;
|
||||
|
||||
// no decals on animating textures, by default
|
||||
if (picnum >= 0)
|
||||
{
|
||||
TexMan[picnum]->bNoDecals = true;
|
||||
}
|
||||
|
||||
while (SC_GetString ())
|
||||
{
|
||||
bool range = false;
|
||||
|
||||
if (SC_Compare ("allowdecals"))
|
||||
{
|
||||
if (picnum >= 0)
|
||||
{
|
||||
TexMan[picnum]->bNoDecals = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (SC_Compare ("range"))
|
||||
{
|
||||
range = true;
|
||||
if (!sink.bUniqueFrames)
|
||||
{
|
||||
SC_ScriptError ("You can only use range once in a single animation.");
|
||||
}
|
||||
if (frames.Size() != 0)
|
||||
{
|
||||
SC_ScriptError ("You cannot use range together with pic.");
|
||||
}
|
||||
}
|
||||
else if (SC_Compare ("pic"))
|
||||
{
|
||||
if (!sink.bUniqueFrames)
|
||||
{
|
||||
SC_ScriptError ("You cannot use pic together with range.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_UnGet ();
|
||||
break;
|
||||
}
|
||||
|
||||
min = max = 1;
|
||||
|
||||
SC_MustGetString ();
|
||||
if (IsNum (sc_String))
|
||||
{
|
||||
framenum = picnum + atoi(sc_String) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
framenum = TexMan.CheckForTexture (sc_String, istex ? FTexture::TEX_Wall : FTexture::TEX_Flat, texflags);
|
||||
if (framenum < 0 && !missing)
|
||||
{
|
||||
SC_ScriptError ("Unknown texture %s", sc_String);
|
||||
}
|
||||
}
|
||||
SC_MustGetString ();
|
||||
if (SC_Compare ("tics"))
|
||||
{
|
||||
SC_MustGetNumber ();
|
||||
if (sc_Number < 0)
|
||||
sc_Number = 0;
|
||||
else if (sc_Number > 255)
|
||||
sc_Number = 255;
|
||||
min = max = sc_Number;
|
||||
}
|
||||
else if (SC_Compare ("rand") && !range)
|
||||
{
|
||||
SC_MustGetNumber ();
|
||||
min = clamp (sc_Number, 0, 255);
|
||||
SC_MustGetNumber ();
|
||||
max = clamp (sc_Number, min, min+255);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_ScriptError ("Must specify a duration for animation frame");
|
||||
}
|
||||
|
||||
if (picnum >= 0)
|
||||
{
|
||||
if (!range)
|
||||
{
|
||||
frame.SpeedMin = min;
|
||||
frame.SpeedRange = max - min;
|
||||
frame.FramePic = framenum;
|
||||
frames.Push (frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
int spread = framenum - picnum;
|
||||
|
||||
sink.bUniqueFrames = false;
|
||||
sink.NumFrames = abs(spread) + 1;
|
||||
sink.Frames[0].SpeedMin = min;
|
||||
sink.Frames[0].SpeedRange = max - min;
|
||||
sink.Countdown = min - 1;
|
||||
sink.AnimType = FAnimDef::ANIM_Forward;
|
||||
if (spread < 0)
|
||||
{
|
||||
sink.AnimType = FAnimDef::ANIM_Backward;
|
||||
TexMan[framenum]->bNoDecals = TexMan[picnum]->bNoDecals;
|
||||
picnum = framenum;
|
||||
sink.BasePic = picnum;
|
||||
}
|
||||
sink.Frames[0].FramePic = picnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (picnum >= 0) // If base pic is not present, don't add this anim
|
||||
{
|
||||
if (frames.Size() < 2 && (sink.bUniqueFrames || sink.NumFrames < 2))
|
||||
{
|
||||
SC_ScriptError ("Animation needs at least 2 frames");
|
||||
}
|
||||
|
||||
if (sink.bUniqueFrames)
|
||||
{
|
||||
sink.Countdown = frames[0].SpeedMin;
|
||||
sink.NumFrames = frames.Size();
|
||||
|
||||
newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1)*sizeof(FAnimDef::FAnimFrame));
|
||||
*newAnim = sink;
|
||||
|
||||
for (i = 0; i < frames.Size(); ++i)
|
||||
{
|
||||
newAnim->Frames[i] = frames[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
|
||||
*newAnim = sink;
|
||||
}
|
||||
|
||||
// See if there is already an anim with the same base pic.
|
||||
// If so, replace it
|
||||
for (i = Anims.Size(); i-- > 0; )
|
||||
{
|
||||
if (Anims[i]->BasePic == picnum)
|
||||
{
|
||||
free (Anims[i]);
|
||||
Anims[i] = newAnim;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Anims.Push (newAnim);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_InitPicAnims
|
||||
//
|
||||
// Load the table of animation definitions, checking for existence of
|
||||
// the start and end of each frame. If the start doesn't exist the sequence
|
||||
// is skipped, if the last doesn't exist, BOOM exits.
|
||||
//
|
||||
// Wall/Flat animation sequences, defined by name of first and last frame,
|
||||
// The full animation sequence is given using all lumps between the start
|
||||
// and end entry, in the order found in the WAD file.
|
||||
//
|
||||
// This routine modified to read its data from a predefined lump or
|
||||
// PWAD lump called ANIMATED rather than a static table in this module to
|
||||
// allow wad designers to insert or modify animation sequences.
|
||||
//
|
||||
// Lump format is an array of byte packed animdef_t structures, terminated
|
||||
// by a structure with istexture == -1. The lump can be generated from a
|
||||
// text source file using SWANTBLS.EXE, distributed with the BOOM utils.
|
||||
// The standard list of switches and animations is contained in the example
|
||||
// source text file DEFSWANI.DAT also in the BOOM util distribution.
|
||||
//
|
||||
// [RH] Rewritten to support BOOM ANIMATED lump but also make absolutely
|
||||
// no assumptions about how the compiler packs the animdefs array.
|
||||
//
|
||||
void P_InitPicAnims (void)
|
||||
{
|
||||
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
|
||||
|
||||
if (Wads.CheckNumForName ("ANIMATED") != -1)
|
||||
{
|
||||
FAnimDef anim, *newAnim;
|
||||
FMemLump animatedlump = Wads.ReadLump ("ANIMATED");
|
||||
const char *animdefs = (const char *)animatedlump.GetMem();
|
||||
const char *anim_p;
|
||||
int pic1, pic2;
|
||||
|
||||
// Init animation
|
||||
|
||||
anim.bUniqueFrames = false;
|
||||
anim.CurFrame = 0;
|
||||
anim.AnimType = FAnimDef::ANIM_Forward;
|
||||
|
||||
for (anim_p = animdefs; *anim_p != -1; anim_p += 23)
|
||||
{
|
||||
if (*anim_p /* .istexture */ & 1)
|
||||
{
|
||||
// different episode ?
|
||||
if ((pic1 = TexMan.CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Wall, texflags)) == -1 ||
|
||||
(pic2 = TexMan.CheckForTexture (anim_p + 1 /* .endname */, FTexture::TEX_Wall, texflags)) == -1)
|
||||
continue;
|
||||
|
||||
if (*anim_p & 2)
|
||||
{ // [RH] Bit 1 set means allow decals on walls with this texture
|
||||
TexMan[pic1]->bNoDecals = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TexMan[pic1]->bNoDecals = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((pic1 = TexMan.CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Flat, texflags)) == -1 ||
|
||||
(pic2 = TexMan.CheckForTexture (anim_p + 1 /* .startname */, FTexture::TEX_Flat, texflags)) == -1)
|
||||
continue;
|
||||
}
|
||||
// [RH] Allow for either forward or backward animations.
|
||||
if (pic1 < pic2)
|
||||
{
|
||||
anim.BasePic = pic1;
|
||||
anim.NumFrames = pic2 - pic1 + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
anim.BasePic = pic2;
|
||||
anim.NumFrames = pic1 - pic2 + 1;
|
||||
anim.AnimType = FAnimDef::ANIM_Backward;
|
||||
}
|
||||
|
||||
anim.bUniqueFrames = false;
|
||||
anim.CurFrame = 0;
|
||||
|
||||
if (anim.NumFrames < 2)
|
||||
I_FatalError ("P_InitPicAnims: bad cycle from %s to %s",
|
||||
anim_p + 10 /* .startname */,
|
||||
anim_p + 1 /* .endname */);
|
||||
|
||||
anim.Frames[0].SpeedMin =
|
||||
/* .speed */
|
||||
(anim_p[19] << 0) |
|
||||
(anim_p[20] << 8) |
|
||||
(anim_p[21] << 16) |
|
||||
(anim_p[22] << 24);
|
||||
|
||||
anim.Frames[0].SpeedRange = 0;
|
||||
anim.Frames[0].FramePic = anim.BasePic;
|
||||
anim.Countdown = anim.Frames[0].SpeedMin - 1;
|
||||
|
||||
newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
|
||||
*newAnim = anim;
|
||||
Anims.Push (newAnim);
|
||||
}
|
||||
}
|
||||
// [RH] Load any ANIMDEFS lumps
|
||||
P_InitAnimDefs ();
|
||||
P_FixAnimations ();
|
||||
}
|
||||
|
||||
void P_AddSimpleAnim (int picnum, int animcount, int animtype, int animspeed)
|
||||
{
|
||||
FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
|
||||
anim->bUniqueFrames = false;
|
||||
anim->CurFrame = 0;
|
||||
anim->BasePic = picnum;
|
||||
anim->NumFrames = animcount;
|
||||
anim->AnimType = animtype;
|
||||
anim->Frames[0].SpeedMin = animspeed;
|
||||
anim->Frames[0].SpeedRange = 0;
|
||||
anim->Frames[0].FramePic = anim->BasePic;
|
||||
anim->Countdown = anim->Frames[0].SpeedMin - 1;
|
||||
Anims.Push (anim);
|
||||
}
|
||||
|
||||
// [RH] Copy the "front sky" flag from an animated texture to the rest
|
||||
// of the textures in the animation, and make every texture in an
|
||||
// animation range use the same setting for bNoDecals.
|
||||
static void P_FixAnimations ()
|
||||
{
|
||||
unsigned int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < Anims.Size(); ++i)
|
||||
{
|
||||
FAnimDef *anim = Anims[i];
|
||||
if (anim->bUniqueFrames)
|
||||
{
|
||||
if (TexMan[anim->BasePic]->bNoRemap0)
|
||||
{
|
||||
for (j = 0; j < anim->NumFrames; ++j)
|
||||
{
|
||||
TexMan[anim->Frames[j].FramePic]->SetFrontSkyLayer ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool nodecals;
|
||||
bool noremap = false;
|
||||
const char *name;
|
||||
|
||||
name = TexMan[anim->BasePic]->Name;
|
||||
nodecals = TexMan[anim->BasePic]->bNoDecals;
|
||||
for (j = 0; j < anim->NumFrames; ++j)
|
||||
{
|
||||
FTexture *tex = TexMan[anim->BasePic + j];
|
||||
noremap |= tex->bNoRemap0;
|
||||
tex->bNoDecals = nodecals;
|
||||
}
|
||||
if (noremap)
|
||||
{
|
||||
for (j = 0; j < anim->NumFrames; ++j)
|
||||
{
|
||||
TexMan[anim->BasePic + j]->SetFrontSkyLayer ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Check dmflags for noexit and respond accordingly
|
||||
bool CheckIfExitIsGood (AActor *self)
|
||||
|
|
@ -1121,9 +568,6 @@ EXTERN_CVAR (Float, timelimit)
|
|||
|
||||
void P_UpdateSpecials ()
|
||||
{
|
||||
unsigned int j;
|
||||
int i;
|
||||
|
||||
// LEVEL TIMER
|
||||
if (deathmatch && timelimit)
|
||||
{
|
||||
|
|
@ -1133,79 +577,6 @@ void P_UpdateSpecials ()
|
|||
G_ExitLevel(0, false);
|
||||
}
|
||||
}
|
||||
|
||||
// ANIMATE FLATS AND TEXTURES GLOBALLY
|
||||
// [RH] Changed significantly to work with ANIMDEFS lumps
|
||||
for (j = 0; j < Anims.Size(); ++j)
|
||||
{
|
||||
FAnimDef *anim = Anims[j];
|
||||
if (--anim->Countdown == 0)
|
||||
{
|
||||
int speedframe;
|
||||
|
||||
switch (anim->AnimType)
|
||||
{
|
||||
case FAnimDef::ANIM_Forward:
|
||||
anim->CurFrame = (anim->CurFrame + 1) % anim->NumFrames;
|
||||
break;
|
||||
|
||||
case FAnimDef::ANIM_Backward:
|
||||
if (anim->CurFrame == 0)
|
||||
{
|
||||
anim->CurFrame = anim->NumFrames - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
anim->CurFrame -= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case FAnimDef::ANIM_OscillateUp:
|
||||
anim->CurFrame = anim->CurFrame + 1;
|
||||
if (anim->CurFrame >= anim->NumFrames - 1)
|
||||
{
|
||||
anim->AnimType = FAnimDef::ANIM_OscillateDown;
|
||||
}
|
||||
break;
|
||||
|
||||
case FAnimDef::ANIM_OscillateDown:
|
||||
anim->CurFrame = anim->CurFrame - 1;
|
||||
if (anim->CurFrame == 0)
|
||||
{
|
||||
anim->AnimType = FAnimDef::ANIM_OscillateUp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
speedframe = (anim->bUniqueFrames) ? anim->CurFrame : 0;
|
||||
|
||||
if (anim->Frames[speedframe].SpeedRange == 0)
|
||||
{
|
||||
anim->Countdown = anim->Frames[speedframe].SpeedMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
anim->Countdown = pr_animatepictures() % anim->Frames[speedframe].SpeedRange
|
||||
+ anim->Frames[speedframe].SpeedMin;
|
||||
}
|
||||
}
|
||||
|
||||
if (anim->bUniqueFrames)
|
||||
{
|
||||
TexMan.SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < anim->NumFrames; i++)
|
||||
{
|
||||
TexMan.SetTranslation (anim->BasePic + i, anim->BasePic + (i + anim->CurFrame) % anim->NumFrames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Scroll the sky
|
||||
sky1pos = sky1pos + level.skyspeed1;
|
||||
sky2pos = sky2pos + level.skyspeed2;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue