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 –
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