DarkOne’s Wolf3D source tutorial ¹2.

Life is a Motion

 

The purpose of this tutorial is to make wall animation in Wolf3D.

 

First we’ll define object code which would be used for animation. We’ll do this in “WL_DEF.H”:

 

Line ~ 54

//

// tile constants

//

 

#define ICONARROWS    90

#define PUSHABLETILE  98

#define EXITTILE            99          // at end of castle

#define ANIMTILE            100

#define AREATILE            107         // first of NUMAREAS floor tiles

#define NUMAREAS            37

#define ELEVATORTILE  21

#define AMBUSHTILE          106

#define ALTELEVATORTILE     107

 

We’ll have a total of 5 different animation speeds (from slowest to fastest). They would be located one after another: 100 – SLOW, 101 – NORMAL, 102 – FAST, 103 – ULTRA. Their purpose is to make wall animation: when there is an animation modifier on the same tile as wall Wolf3D would display an animation of 3 frames (looped) – frame 1: actual wall graphics (as if without modifier) frames 2 and 3: the graphics after original graphics. It opens endless possibilities in wolf editing. Of course you can make longer animation, or shorter.

 

He we go with actual code: We are modifying file “WL_DRAW.C”:

 

Line ~ 480

void HitVertWall (void)

{

    int               wallpic;

    unsigned    texture;

 

    texture = (yintercept>>4)&0xfc0;

    if (xtilestep == -1)

    {

          texture = 0xfc0-texture;

          xintercept += TILEGLOBAL;

    }

    wallheight[pixx] = CalcHeight();

 

    switch(*(mapsegs[1]+farmapylookup[ytile]+xtile))

    {

    case ANIMTILE:

          tilehit+=(frameon>>6)%3;

          break;

    case ANIMTILE+1:

          tilehit+=(frameon>>5)%3;

          break;

    case ANIMTILE+2:

          tilehit+=(frameon>>4)%3;

          break;

    case ANIMTILE+3:

          tilehit+=(frameon>>3)%3;

          break;

    case ANIMTILE+4:

          tilehit+=(frameon>>2)%3;

          break;

    }

 

    if (lastside==1 && lastintercept == xtile && lasttilehit == tilehit)

    {

          // in the same wall type as last time, so check for optimized draw

          if (texture == (unsigned)postsource)

          {

          // wide scale

                postwidth++;

                wallheight[pixx] = wallheight[pixx-1];

                return;

          }

          else

          {

                ScalePost ();

                (unsigned)postsource = texture;

                postwidth = 1;

                postx = pixx;

          }

    }

    else

    {

    // new wall

          if (lastside != -1)          // if not the first scaled post

                ScalePost ();

 

          lastside = true;

          lastintercept = xtile;

 

          lasttilehit = tilehit;

          postx = pixx;

          postwidth = 1;

 

          if (tilehit & 0x40)

          {                                  // check for adjacent doors

                ytile = yintercept>>TILESHIFT;

                if ( tilemap[xtile-xtilestep][ytile]&0x80 )

                      wallpic = DOORWALL+3;

                else

                      wallpic = vertwall[tilehit & ~0x40];

          }

          else

                wallpic = vertwall[tilehit];

 

          *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic);

          (unsigned)postsource = texture;

 

    }

Line ~ 550

void HitHorizWall (void)

{

    int               wallpic;

    unsigned    texture;

 

    texture = (xintercept>>4)&0xfc0;

    if (ytilestep == -1)

          yintercept += TILEGLOBAL;

    else

          texture = 0xfc0-texture;

    wallheight[pixx] = CalcHeight();

 

    switch(*(mapsegs[1]+farmapylookup[ytile]+xtile))

    {

    case ANIMTILE:

          tilehit+=(frameon>>6)%3;

          break;

    case ANIMTILE+1:

          tilehit+=(frameon>>5)%3;

          break;

    case ANIMTILE+2:

          tilehit+=(frameon>>4)%3;

          break;

    case ANIMTILE+3:

          tilehit+=(frameon>>3)%3;

          break;

    case ANIMTILE+4:

          tilehit+=(frameon>>2)%3;

          break;

    }

 

    if (lastside==0 && lastintercept == ytile && lasttilehit == tilehit)

    {

          // in the same wall type as last time, so check for optimized draw

          if (texture == (unsigned)postsource)

          {

          // wide scale

                postwidth++;

                wallheight[pixx] = wallheight[pixx-1];

                return;

          }

          else

          {

                ScalePost ();

                (unsigned)postsource = texture;

                postwidth = 1;

                postx = pixx;

          }

    }

    else

    {

    // new wall

          if (lastside != -1)          // if not the first scaled post

                ScalePost ();

 

          lastside = 0;

          lastintercept = ytile;

 

          lasttilehit = tilehit;

          postx = pixx;

          postwidth = 1;

 

          if (tilehit & 0x40)

          {                            // check for adjacent doors

                xtile = xintercept>>TILESHIFT;

                if ( tilemap[xtile][ytile-ytilestep]&0x80 )

                      wallpic = DOORWALL+2;

                else

                      wallpic = horizwall[tilehit & ~0x40];

          }

          else

                wallpic = horizwall[tilehit];

 

          *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic);

          (unsigned)postsource = texture;

    }

 

}

 

That’s it. Just draw an animation (of 3 frames) add it to wolf data files as a sequential wall textures, make a map in your favorite map editor, setting animation flag (just like you set push (secret) wall flag) and here we go: flashing light, computer screens, fire in fireplace…

Note: there is no performance hit with such an animation, you can even make each and every tile on the map animated and engine wouldn’t even notice this..

Just another note: you may use all animation frames as a separate wall textures

Last note: I hope this thing helped you on your way to create the best Wolf3D conversion ever made. If so, just drop me a line on DarkOne@navigators.lv. I wish to see your work!

 

--

© 2002 DarkOne; part of NewWolf project

http://wolfgl.narod.ru

DarkOne@navigators.lv

Hosted by uCoz