DieHard Wolfers Forum Index DieHard Wolfers
A Wolfenstein 3d Fan Community


  Hosted by: MCS & Areyep.com - Designed by: BrotherTank

Original Yahoo Forum - Die Hard Archives

AReyeP HomepageAreyep Homepage DieHard Wolfenstein BunkerDieHard Wolfenstein Bunker Log inLog in RegisterRegister Banlist FAQFAQ Search ForumsSearch

  Username:    Password:      Remember me       

[Code] Directional Sprites - Ripper
Page 1 of 1
DieHard Wolfers Forum Index -> Code Tutorials View Previous TopicRefresh this PageAdd Topic to your Browser FavoritesSearch ForumsPrint this TopicE-mail TopicGoto Page BottomView Next Topic
Post new topicReply to topic
Author Message
BrotherTank
Forum Administrator
<B>Forum Administrator</B>


Joined: 01 Mar 2003
Last Visit: 13 Sep 2017

Topics: 153
Posts: 2256
Location: Ontario
canada.gif

PostPosted: Tue Mar 16, 2004 12:10 pm
   Subject: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Next PostGoto Bottom of Posts

Formatting is a little messed up but...

Directional 3D sprites
By Ripper

Hi and welcome to my first tutorial for Wolfenstein 3D ;D
I hope this will help you make some of your dreams come true Wink

As you may already have noticed, this tutorial wants to teach you, how to include "directional 3D sprites" into your Wolfenstein 3D engine. But first of all: WHAT THE HELL ARE "directional 3D sprites" ???

To explain this remember those glass sprites in some TCs which were used to make a glass wall between two wall sides. When you looked perpendicularly at them, they looked all nice. But when you turned a bit around and looked at them again, you should have noticed, that they turned with you! Or another example: you probably remember some outdoor scenes with fences painted on walls. Or imagine a house/bunker with windows! With normal sprites this is impossible if you don't want the user to only run straight forward to the window *gg*

But before I start telling you how you can add it to your own TC or whatever, I want to reveal some negative points you'll have to remember when trying to add directional sprites:

  • The first two (didn't tried just one yet) and the last column of a sprites image have to be empty or Wolfenstein 3D will crash when it tries to paint the sprites. Update: With DarkOne's sprite bug fix, you'll be able to use all 64 columns (keeping the next point in mind)!

  • Due to the limitation to 4096 bytes per sprite it isn't possible yet to make a "wall" sprite as tall as a normal wall without using some tricks I won't mention here.

  • This feature is rather powerful as there are many possiblities you can use it. With some individual code changes you can even create turning doors and many other things you can't even imagine *gg* But of course that's why it's "a little bit" complicated so at first you'll have to play around with it before you get used to it. This is mainly because of the limited map format which only allows simple object numbers and no individual data for a object at all (i.e. an integer to provide an angle). That's why we'd have to create a new object for every angle used inside a map (this version only supports two different angles, but you can implement more angles, of course). Not very nice, but currently the only way

  • As you should know, playing around with the source code of Wolfenstein 3D causes many system crashes which are too often binded with data loss (i.e. I lost hundreds of MB because my whole system crashed many times during downloads... very funny... ). So you're the only one responsible for what happens if your Wolfenstein 3D engine doesn't do the things it should, say it crashes! But you should already be used to it Wink

  • In the following code there seems to be at least one "wolf only crash" causing bug which appears extremly rare when running through such sprites. So you can find the bug and kill it, prohibit running through directional 3d sprites or leave the bug doing what he wants to do. It's probably a division error...

  • Although the sprites are sorted by distance it is possible that they are drawn in the wrong order when having differently positioned sprites next to each other:

  • Probably some other things I can't remember right now Wink


Now that this is said, let's start:

At first make sure your current version of Wolfenstein 3D is working without major problems, though it would be perfectly if it would run without any problems, but that's a rare situation, isn't it? Then make a backup of your current source code, so that you won't be unable to restore the working status.

Now open your WL_SCALE.C and append (add) the following code to the end of the file:

::: CODE :::
void Scale3DShaper (int x1,int x2,int shapenum,unsigned height1,unsigned height2,
      fixed ny1,fixed ny2,fixed nx1,fixed nx2)
{
   t_compshape _seg *shape;
   t_compscale _seg *comptable;
   unsigned scale1,scale2;
   unsigned far *cmdptr;
   int dx=x2-x1,len,i;
   fixed height,dheight;
   int xpos[65];
   fixed dxx=(ny2-ny1)<<8,dzz=(nx2-nx1)<<8;
   fixed dxa=0,dza=0;

   if(!dx) return;

   height=((fixed)height1)<<12+2048;
   dheight=(((fixed)height2-(fixed)height1)<<12)/(fixed)dx;

   // Get length/address of pixeldata
   shape = PM_GetSpritePage (shapenum);

   scale1 = height1>>3; // low three bits are fractional
   scale2 = height2>>3; // low three bits are fractional
   if (!scale1 && !scale2 || scale1>maxscale && scale2>maxscale)
      return; // too close or far away*/

   len=shape->rightpix-shape->leftpix;
   if(!len) return;

   dxx/=len,dzz/=len;

   xpos[0]=(int)((ny1+(dxa>>8))*scale/(nx1+(dza>>8))+centerx);
   for(i=1;i<=len;i++)
   {
      dxa+=dxx,dza+=dzz;
      xpos[i]=(int)((ny1+(dxa>>8))*scale/(nx1+(dza>>8))+centerx);
      if(xpos[i-1]>viewwidth) break;
   }
   len=i-1;

   *(((unsigned *)&linecmds)+1)=(unsigned)shape; // seg of shape

   cmdptr = &shape->dataofs[0];
   slinewidth = 1;
   i=0;
   if(x2>viewwidth) x2=viewwidth;

   for(i=0;i<len;i++)
   {
      for(slinex=xpos[i];slinex<xpos[i+1] && slinex<x2;slinex++)
      {
         height+=dheight;
         if(slinex<0) continue;

         scale1=(unsigned)(height>>15);

         if(wallheight[slinex]<(height>>12) && scale1 && scale1<=maxscale)
         {
            comptable = scaledirectory[scale1];

            *(((unsigned *)&linescale)+1)=(unsigned)comptable; // seg of far call

            (unsigned)linecmds=cmdptr[i];
            ScaleLine();
         }
      }
   }
}

extern long playx,playy;

void Scale3DShape(statobj_t *ob)
{
   fixed nx1,nx2,ny1,ny2;
   int viewx1,viewx2;
   long height1,height2;
   fixed diradd;

//
// the following values for "diradd" aren't optimized yet
// if you have problems with sprites being visible through wall edges
// where they shouldn't, you can try to adjust these values and
// the -1024 and +2048 in both "if" blocks
//

   if(ob->flags & FL_DIRFORWARD) diradd=0x7ff0+0x8000;
   else if(ob->flags & FL_DIRBACKWARD) diradd=-0x7ff0+0x8000;
   else diradd=0x8000;

   if(ob->flags & FL_DIREAST)
   {
      fixed gx1,gx2,gy,gxt1,gxt2,gyt;
//
// translate point to view centered coordinates
//
      gx1 = (((long)ob->tilex) << TILESHIFT)+0x8000-playx-0x8000L-1024;
      gx2 = gx1+0x10000L+2048;
      gy = (((long)ob->tiley) << TILESHIFT)+diradd-playy;

//
// calculate newx
//
      gxt1 = FixedByFrac(gx1,viewcos);
      gxt2 = FixedByFrac(gx2,viewcos);
      gyt = FixedByFrac(gy,viewsin);
      nx1 = gxt1-gyt-0x2000;
      nx2 = gxt2-gyt-0x2000;

//
// calculate newy
//
      gxt1 = FixedByFrac(gx1,viewsin);
      gxt2 = FixedByFrac(gx2,viewsin);
      gyt = FixedByFrac(gy,viewcos);
      ny1 = gyt+gxt1;
      ny2 = gyt+gxt2;
   }
   else
   {
      fixed gy1,gy2,gx,gyt1,gyt2,gxt;
//
// translate point to view centered coordinates
//
      gy1 = (((long)ob->tiley) << TILESHIFT)+0x8000-playy-0x8000L-1024;
      gy2 = gy1+0x10000L+2048;
      gx = (((long)ob->tilex) << TILESHIFT)+diradd-playx;

//
// calculate newx
//
      gxt = FixedByFrac(gx,viewcos);
      gyt1 = FixedByFrac(gy1,viewsin);
      gyt2 = FixedByFrac(gy2,viewsin);
      nx1 = gxt-gyt1-0x2000;
      nx2 = gxt-gyt2-0x2000;

//
// calculate newy
//
      gxt = FixedByFrac(gx,viewsin);
      gyt1 = FixedByFrac(gy1,viewcos);
      gyt2 = FixedByFrac(gy2,viewcos);
      ny1 = gyt1+gxt;
      ny2 = gyt2+gxt;
   }

//
// calculate perspective ratio
//
   if(nx1>=0 && nx1<=1792) nx1=1792;
   if(nx1<0 && nx1>=-1792) nx1=-1792;
   if(nx2>=0 && nx2<=1792) nx2=1792;
   if(nx2<0 && nx2>=-1792) nx2=-1792;

   viewx1=(int)(centerx+ny1*scale/nx1);
   viewx2=(int)(centerx+ny2*scale/nx2);

//
// calculate height (heightnumerator/(nx>>8)) (heightnumerator=0x36800)
//
   asm mov ax,word ptr heightnumerator
   asm mov dx,word ptr heightnumerator+2
   asm idiv word ptr nx1+1 // nx1>>8
   asm mov word ptr height1,ax
   asm mov word ptr height1+2,dx

   asm mov ax,word ptr heightnumerator
   asm mov dx,word ptr heightnumerator+2
   asm idiv word ptr nx2+1 // nx2>>8
   asm mov word ptr height2,ax
   asm mov word ptr height2+2,dx

   if(viewx2 < viewx1)
      Scale3DShaper(viewx2,viewx1,ob->shapenum,(unsigned)height2,
         (unsigned)height1,ny2,ny1,nx2,nx1);
   else
      Scale3DShaper(viewx1,viewx2,ob->shapenum,(unsigned)height1,
         (unsigned)height2,ny1,ny2,nx1,nx2);
}


Update: At this point I'll insert DarkOne's sprite bug fix, so that you'll be able to use full width sprites.

Replace the ScaleShape and SimpleScaleShape functions with the following functions:

::: CODE :::
void ScaleShape (int xcenter, int shapenum, unsigned height)
{
   t_compshape _seg *shape;
   t_compscale _seg *comptable;
   unsigned scale,srcx,startx,stopx,next_x;
   unsigned far *cmdptr;
   boolean leftvis, rightvis;

   shape=PM_GetSpritePage(shapenum);

   scale=height>>3; // low three bits are fractional
   if(!scale || scale>maxscale) return; // too close or far away
   comptable=scaledirectory[scale];

   *(((unsigned *)&linescale)+1)=(unsigned)comptable; // seg of far call
   *(((unsigned *)&linecmds)+1)=(unsigned)shape; // seg of shape

   next_x=slinex=xcenter-scale;
   cmdptr=shape->dataofs;
   startx=shape->leftpix;
   stopx=shape->rightpix;

   for(srcx=0; srcx<=stopx; srcx++, slinex=next_x)
   {
      if(slinex>=viewwidth) break; // off the screen

      slinewidth=comptable->width[srcx];
      next_x+=slinewidth; // next slinex
      if(srcx<startx) continue; // before the shape

      (unsigned)linecmds=*cmdptr++;

      if(!slinewidth) continue;

      if(slinewidth==1)
      {
         if(slinex<0 || slinex>=viewwidth) continue;

         if(wallheight[slinex]>=height) continue; // obscured by closer wall
         ScaleLine();
      }
      else
      {
         if(slinex<0)
         {
            if(slinewidth<=-slinex) continue; // still off the left edge

            slinewidth-=slinex;
            slinex=0;
         }
         else if(slinex+slinewidth>viewwidth)
            slinewidth=viewwidth-slinex;

         leftvis=(wallheight[slinex]<height);
         rightvis=(wallheight[slinex+slinewidth-1]<height);

         if(leftvis)
         {
            if(rightvis)
               ScaleLine();
            else
            {
               while(wallheight[slinex+slinewidth-1]>=height) slinewidth--;
               ScaleLine();
               break; // the rest of the shape is gone
            }
         }
         else
         {
            if(rightvis)
            {
               while(wallheight[slinex]>=height)
               {
                  slinex++;
                  slinewidth--;
               }
               ScaleLine ();
            }
            else
               continue; // totally obscured
         }
      }
   }
}

void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
{
   t_compshape _seg *shape;
   t_compscale _seg *comptable;
   unsigned scale,srcx,startx,stopx,next_x;
   int t;
   unsigned far *cmdptr;
   boolean leftvis,rightvis;


   shape = PM_GetSpritePage (shapenum);

   scale = height>>1;
   comptable = scaledirectory[scale];

   *(((unsigned *)&linescale)+1)=(unsigned)comptable; // seg of far call
   *(((unsigned *)&linecmds)+1)=(unsigned)shape; // seg of shape

   next_x=slinex=xcenter-scale;
   cmdptr=shape->dataofs;
   startx=shape->leftpix;
   stopx=shape->rightpix;

   for(srcx=0; srcx<=stopx; srcx++, slinex=next_x)
   {
      if(slinex>=viewwidth) break; // off the screen

      slinewidth=comptable->width[srcx];
      next_x+=slinewidth; // next slinex
      if(srcx<startx) continue; // before the shape

      (unsigned)linecmds=*cmdptr++;

      if(!slinewidth) continue;

      if(slinewidth==1)
      {
         if(slinex<0 || slinex>=viewwidth) continue;

         ScaleLine();
      }
      else
      {
         if(slinex<0)
         {
            if(slinewidth<=-slinex) continue; // still off the left edge

            slinewidth-=slinex;
            slinex=0;
         }
         else if(slinex+slinewidth>viewwidth)
            slinewidth=viewwidth-slinex;

         ScaleLine();
      }
   }
}


If you use the normal SetupScaling function, very near walls and sprites get pixelized upper and lower edges because they optimized the scalers to save some memory. For normal walls and sprites that's ok, but for directional 3D sprites you'll probably see the difference.

So IF you don't want very near sprites to look pixelized, you'll have to change the SetupScaling function at the very begining of WL_SCALE.C. There you have to comment out the following red marked lines by adding a "//" in front of them:

::: CODE :::
//
// free up old scalers
//
   for (i=1;i<MAXSCALEHEIGHT;i++)
   {
      if (scaledirectory[i])
         MM_FreePtr (&(memptr)scaledirectory[i]);
      if (i>=stepbytwo)
         i += 2;
   }
   memset (scaledirectory,0,sizeof(scaledirectory));

   MM_SortMem ();

//
// build the compiled scalers
//
   stepbytwo = viewheight/2; // save space by double stepping
   MM_GetPtr (&(memptr)work,20000);

   for (i=1;i<=maxscaleheight;i++)
   {
      BuildCompScale (i*2,&(memptr)scaledirectory[i]);
      if (i>=stepbytwo)
         i+= 2;

   }
   MM_FreePtr (&(memptr)work);

//
// compact memory and lock down scalers
//
   MM_SortMem ();
   for (i=1;i<=maxscaleheight;i++)
   {
      MM_SetLock (&(memptr)scaledirectory[i],true);
      fullscalefarcall[i] = (unsigned)scaledirectory[i];
      fullscalefarcall[i] <<=16;
      fullscalefarcall[i] += scaledirectory[i]->codeofs[0];
      if (i>=stepbytwo)
      {
         scaledirectory[i+1] = scaledirectory[i];
         fullscalefarcall[i+1] = fullscalefarcall[i];
         scaledirectory[i+2] = scaledirectory[i];
         fullscalefarcall[i+2] = fullscalefarcall[i];
         i+=2;
      }

   }
   scaledirectory[0] = scaledirectory[1];
   fullscalefarcall[0] = fullscalefarcall[1];


Now let's go the next file WL_DRAW.C:
First add the following line at the begining right under GLOBAL VARIABLES
::: CODE :::
long playx,playy;


Then go to the DrawScaleds function and add the following blue marked lines:

::: CODE :::
#define MAXVISABLE   50

typedef struct
{
   int  viewx,
         viewheight,
         shapenum;
   statobj_t *transsprite;
} visobj_t;

visobj_t   vislist[MAXVISABLE],*visptr,*visstep,*farthest;
void Scale3DShape(statobj_t *ob);


void DrawScaleds (void)
{
   int i,j,least,numvisable,height;

[...]

      if (!visptr->viewheight)
         continue; // to close to the object
      if(statptr->flags & (FL_DIRSOUTH | FL_DIREAST))
         visptr->transsprite=statptr;
      else
         visptr->transsprite=NULL;

      if (visptr < &vislist[MAXVISABLE-1]) // don't let it overflow
         visptr++;

[...]

         if (obj->state->rotate)
            visptr->shapenum += CalcRotate (obj);
         if (visptr < &vislist[MAXVISABLE-1]) // don't let it overflow

         {
            visptr->transsprite=NULL;

           visptr++;
         }
        obj->flags |= FL_VISABLE;

[...]

      //
      // draw farthest
      //
      if(farthest->transsprite)
         Scale3DShape(farthest->transsprite);
      else

         ScaleShape(farthest->viewx,farthest->shapenum,farthest->viewheight);

      farthest->viewheight = 32000;
   }


The last change in this file is in the ThreeDRefresh function:

::: CODE :::

//
// draw all the scaled images
//
   playy=(player->y+FixedByFrac(0x7300,viewsin));
   playx=(player->x-FixedByFrac(0x7300,viewcos));

   DrawScaleds();             // draw scaled stuff
   DrawPlayerWeapon ();  // draw player's hands
[/quote]

Your next victim (file to edit) is WL_DEF.H some pages under GLOBAL CONSTANTS

[quote="code"]// object flag values

#define FL_SHOOTABLE 1
#define FL_BONUS 2
#define FL_NEVERMARK 4
#define FL_VISABLE 8
#define FL_ATTACKMODE 16
#define FL_FIRSTATTACK 32
#define FL_AMBUSH 64
#define FL_NONMARK 128

#define FL_DIRSOUTH 16
#define FL_DIREAST 32
#define FL_DIRFORWARD 64
#define FL_DIRBACKWARD 128



Then go to GLOBAL TYPES and add these blue lines:

::: CODE :::
   bo_machinegun,
   bo_chaingun,
   bo_food,
   bo_fullheal,
   bo_25clip,
   bo_spear,   // add a comma to the end of bo_spear as shown
   dir_south,
   dir_south_fw,
   dir_south_bw,
   dir_east,
   dir_east_fw,
   dir_east_bw,
   bl_dir_south,
   bl_dir_south_fw,
   bl_dir_south_bw,
   bl_dir_east,
   bl_dir_east_fw,
   bl_dir_east_bw



Now let's change WL_ACT1.C! When you're already here, you can also add two example directional sprites. For that go to the end of the object list and add the blue lines:

::: CODE :::
   
//
// NEW PAGE
//
#ifdef SPEAR
{SPR_STAT_48,block},         // marble pillar
{SPR_STAT_49,bo_25clip},      // bonus 25 clip
{SPR_STAT_50,block},         // truck
{SPR_STAT_51,bo_spear},       // SPEAR OF DESTINY!
#endif

{SPR_STAT_26,bo_clip2},       // Clip            "

{SPR_STAT_47,dir_south},
{SPR_STAT_47,bl_dir_east},

{-1}                     // terminator
};


In the SpawnStatic function you have to add this(in blue again):

::: CODE :::
   case bo_alpo:
   case bo_gibs:
   case bo_spear:
      laststatobj->flags = FL_BONUS;
      laststatobj->itemnumber = statinfo[type].type;
      break;
   case bl_dir_south:
   case bl_dir_south_fw:
   case bl_dir_south_bw:
      (unsigned)actorat[tilex][tiley] = 1; // consider it a blocking tile
   case dir_south:
   case dir_south_fw:
   case dir_south_bw:
      laststatobj->flags=FL_DIRSOUTH;
      break;
   case bl_dir_east:
   case bl_dir_east_fw:
   case bl_dir_east_bw:
      (unsigned)actorat[tilex][tiley] = 1; // consider it a blocking tile
   case dir_east:
   case dir_east_fw:
   case dir_east_bw:
      laststatobj->flags=FL_DIREAST;
      break;
   }
   switch(statinfo[type].type)
   {
      case dir_south_fw:
      case bl_dir_south_fw:
      case dir_east_fw:
      case bl_dir_east_fw:
         laststatobj->flags|=FL_DIRFORWARD;
         break;
      case dir_south_bw:
      case bl_dir_south_bw:
      case dir_east_bw:
      case bl_dir_east_bw:
         laststatobj->flags|=FL_DIRBACKWARD;
         break;

   }

   laststatobj++;

   if (laststatobj == &statobjlist[MAXSTATS])
      Quit ("Too many static objects!\n");
}


Update: While updating this tutorial, I noticed, that I forgot to mention a source code change in the WL_GAME.C to make the example work...
You've got to add the following blue lines in the ScanInfoPlane function:

::: CODE :::
         case 70:
#ifdef SPEAR
         case 71:
         case 72:
         case 73:            // TRUCK AND SPEAR!
         case 74:
#endif
         case 72:
         case 73:

            SpawnStatic(x,y,tile-23);
            break;


That were all source code changes for now ;D
So all what's left is to include some directional 3D sprites into your map! I'll only explain this for FloEdit, because it's the only editor I have and use (I know it's crashing a little bit too much, but I'm not responsible for making maps )
After you have connected to your Wolfenstein 3D files you'll be using for this engine, go into the Professional mode dialog under "Extra". There click on Add new record and enter the following values:


  • New ID: 72
  • Description: Vines N/S
  • Kind: Object
  • Database position: 10000


Then once again Add new record:


  • New ID: 73
  • Description: Vines W/E
  • Kind: Object
  • Database position: 10001


Now you'll just have to add those objects (as many times as you wish (more or less )), save your changes, compile your wolf3d engine and watch the results ;D
If everything works, you can add more directional 3D sprites using your own graphics and individual sprite states (I'll explain just in a minute).
If it doesn't work, then I have no idea right now (while I'm writing this text ). Read through the tutorial carefully and see if you forgot something.
This tutorial was tested with Borland C++ 3.1 and Borland C++ 4.02 so it should really work, if you started with a working standard wolf engine. Of course there could be problems with non standard engines i.e. when trying to add this feature to an already modified engine. In that case you'll have to find a way to fix it. Perhaps add this feature here to a working standard wolf engine and add your individual features to this engine step by step. Then you should be able to find the point where it stops working.
If it still won't work, wait one day and try again Wink
If it just can't be helped, try to contact me. But FIRST try to help yourself !!!

You may have noticed, that we added a small amount of different directional 3D sprites:

  • dir_south, dir_south_fw, dir_south_bw
  • dir_east, dir_east_fw, dir_east_bw
  • bl_dir_south, bl_dir_south_fw, bl_dir_south_bw
  • bl_dir_east, bl_dir_east_fw, bl_dir_east_bw


First a sprite can have one of two different directions which the sprite runs along: south and east (or north and west, what ever you want). These directions correspond to the directions when looking at your map in an editor.
Then a sprite can be blocking so that you can't walk through it, though enemies can see you through them even if you can't. This is marked by a bl.
The last option you have is the position inside a map tile. The sprite can be in the middle or on one of two edges depending on whether fw (forward) or bw (backward) is used and of course which direction.

I hope you got an idea of those states, but you'll probably just have play around a bit with them Wink

So here's a quick reference, what you have to do to add a new directional sprite:


  • Add a new sprite constant to WL_DEF.H (for own sprite images only)
  • Add a new object with the correct sprite constant and state to the statinfo array in WL_ACT1.C
  • Add a new "case" line with the correct object number inside the ScanInfoPlane function in WL_GAME.C
    (the object number of the first object after the "bo_clip2" clip is 72)
  • Add your new sprite image to the VSWAP.WL6 using your Wolf3D editor (for own sprite images only)
  • Add the new object with the object number from above to your Wolf3D editor
  • Add the new object to your maps Wink


Just remember when adding own sprite images that you'll have to leave the edges on the left and on the right empty, if you don't like your Wolf3D to crash *gg*

Also you should make sure, that your project doesn't contain WOLFHACK.C and WHACK_A.ASM, because the first file eats up 1622 bytes of your DATA segment and the second uses 8192 additional bytes of your main memory. But neither file is needed or used at all! Without these files you will have 1705 free bytes in your DATA segment instead of 83 bytes... Small difference, he?
With this amount of free memory you should be able to add enough objects, sounds or whatever you need to make your TC become perfect without any annoying "Abnormal programm termination" messages

So have a lot of fun with this feature, keep developing it and give us some credits if you use it ;D

Thanks for reading this and cu later Wink

Ripper
JackaL
DieHard SS
DieHard SS


Joined: 25 Jun 2004
Last Visit: 04 Apr 2011

Topics: 30
Posts: 335
Location: Rotorua, New Zealand
newzealand.gif

PostPosted: Fri Aug 19, 2005 1:58 am
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

I got this problem ages ago but forgot to post for help, now that I've got back into my TC I suppose I'll ask.
My code had textured flats and shading in it, (as well as heaps more but these were the major ones) I tried to add the directional sprites code and when I went to compile it all up I got error messages, I believe it was a conflict with the shading (SHADE_A.ASM) I think... Think
- Should I restart the code but instead add direction sprites THEN shading?
- Or should I retry the directional sprites tutorial in case I missed something?

Thanks
WLHack
DieHard Wolfer
DieHard Wolfer


Joined: 10 Jul 2005
Last Visit: 29 Mar 2017

Topics: 65
Posts: 1237
Location: Loppi - Finland
finland.gif

PostPosted: Wed Aug 31, 2005 6:54 am
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

I think I know why you got this problem. I suppose you deleted MapMask declaration
in the end of SimpleScaleShape function.
WLHack
DieHard Wolfer
DieHard Wolfer


Joined: 10 Jul 2005
Last Visit: 29 Mar 2017

Topics: 65
Posts: 1237
Location: Loppi - Finland
finland.gif

PostPosted: Fri Sep 09, 2005 11:41 am
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Can anyone tell how to get this strange "bug".
When I come near the directional sprites, they don't rotate
anymore (what is good) but instead move left and right or backward
and forward, depending on which direction the sprite is facing.
I would be pleased if anyone could help.
lwmxynedtodth
DieHard Officer
DieHard Officer


Joined: 28 May 2006
Last Visit: 22 Aug 2017

Topics: 38
Posts: 570
Location: Neverland
netherlands.gif

PostPosted: Mon Oct 16, 2006 11:58 am
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Hey,
I just got a question out of curiosity. I just applied this tutorial (already for the fourth time, but who cares).
Drawed a new sprite, an archway, and placed it on the chunk of the green barrel and the other one on the table chunk.
I compiled as usual, sure everything works fine. I tested my level with these new static objects. From the front it looked fine,
a nice archway combined with a ceiling tile to look real. I walked under it, to see it from the other side.
But huh, the sprite actually swapped sides. It was weird mirrored, I checked again and I was right.
After a lot of messing around with my code and chunks I figured that it works fine on other chunks, but not on the first
and the second. So I did put it on another and now I'm set. But how could it happen? Why did it mirrored itself, but works fine on another chunk? Really weird, isn't it.

- lwmxynedtodth

EDIT: it seems that what I said was wrong. It actually solved nothing, gonna mess with my code again.

_________________
lwmxynedtodth (portfolio, blog and more)
Killer-suit: Masterminds
On a MMORPG trip.
lwmxynedtodth
DieHard Officer
DieHard Officer


Joined: 28 May 2006
Last Visit: 22 Aug 2017

Topics: 38
Posts: 570
Location: Neverland
netherlands.gif

PostPosted: Mon Oct 16, 2006 11:51 pm
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Well, I don't know what is causing this weird bug now. I thought I'd solved it, but it was not.
This is as I said the fourth time I implemented this tutorial in a code, and this never occured.
So this is the problem: when I view from side one (say facing north), the sprite is drawn correctly.
When I'm facing south then, the sprite is actually mirrored. It occurs at all sprite states, and all sprite chunks.
I used build all, not only compile and make. Any help would be greatly appreciated.

- lwmxynedtodth

_________________
lwmxynedtodth (portfolio, blog and more)
Killer-suit: Masterminds
On a MMORPG trip.
the_fish
Bring 'em On
Bring 'em On


Joined: 18 Nov 2006
Last Visit: 07 Nov 2008

Topics: 12
Posts: 133
Location: England
uk.gif

PostPosted: Sat Dec 16, 2006 12:00 pm
   Subject: Update for Wolf4GW
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

@lwmxynedtodth: (man, that's hard to remember. What's it stand for/mean?) Don't know whether you've given up on that bug yet, from what I can gather from the code it should always occur as the sprite is always drawn from left to right regardless of which way you view it.

I guess no-one's pointed this out before because most directional sprites will be windows/fences etc, which are generally symmetric (that's certainly the case in my TC, so I wouldn't have noticed otherwise). I'd look at passing an extra argument to the Scale3DShaper function to then draw the sprite from the other direction (I'm sure it's possible, I'm just not sure exactly how...).




Another nasty one, took a while to adapt for Ripper's Wolf4GW. It took me ages to see the assembly at the end of Scale3DShape to calculate height1/height2 wasn't working properly. Sad

Place the following functions in WL_DRAW.cpp as WL_SCALE no longer exists, and prototype them at the start accordingly. The rest of the tutorial should work the same.

::: CODE :::

void Scale3DShaper (int x1,int x2,int shapenum,unsigned height1,unsigned height2,
                fixed ny1,fixed ny2,fixed nx1,fixed nx2)
{
        t_compshape *shape;
        unsigned scale1,scale2,starty,endy;
        word *cmdptr;
        word *line;
        byte *vmem;
        int dx=x2-x1,len,i,j,newstart,ycnt,pixheight,screndy,upperedge,scrstarty;
        fixed height,dheight;
        int xpos[65];
        int slinex;
        fixed dxx=(ny2-ny1)<<8,dzz=(nx2-nx1)<<8;
        fixed dxa=0,dza=0;
        byte mask,col;
#ifdef SHADE_COUNT
        byte shade;
        byte *curshades;
#endif


        if(!dx) return;

        height=(((fixed)height1)<<12)+2048;
        dheight=(((fixed)height2-(fixed)height1)<<12)/(fixed)dx;

        // Get length/address of pixeldata
        shape =(t_compshape *)(Pages+((PMSpriteStart+shapenum)<<12));

        scale1 = height1>>3; // low three bits are fractional
        scale2 = height2>>3; // low three bits are fractional
        if (!scale1 && !scale2 /*|| scale1>maxscale && scale2>maxscale*/)
                return; // too close or far away
               

        len=shape->rightpix-shape->leftpix+1;
        if(!len) return;

       
        ny1+=dxx>>9;
        nx1+=dzz>>9;

        dxa=-(dxx>>1),dza=-(dzz>>1);
        dxx>>=6,dzz>>=6;
       
        dxa+=shape->leftpix*dxx,dza+=shape->leftpix*dzz;

        xpos[0]=(int)((ny1+(dxa>>8))*scale/(nx1+(dza>>8))+centerx);

        for(i=1;i<=len;i++)
        {
                dxa+=dxx,dza+=dzz;
                xpos[i]=(int)((ny1+(dxa>>8))*scale/(nx1+(dza>>8))+centerx);
                if(xpos[i-1]>viewwidth) break;
        }
        len=i-1;

        //*(((unsigned *)&line)+1)=(unsigned)shape; // seg of shape
        cmdptr = (word *) &shape->dataofs[0];
        //*(((unsigned *)&vmem)+1)=0xa000;

        i=0;
        if(x2>viewwidth) x2=viewwidth;

        for(i=0;i<len;i++)
        {
                for(slinex=xpos[i];slinex<xpos[i+1] && slinex<x2;slinex++)
                {
                        height+=dheight;
                        if(slinex<0) continue;

                       

                        scale1=(unsigned)(height>>15);

                        if(wallheight[slinex]<(height>>12) && scale1 /*&& scale1<=maxscale*/)
                        {
#ifdef SHADE_COUNT
                                shade=(scale1<<2)/((maxscaleshl2>>8)+1+LSHADE_flag);
                                if(shade>32) shade=32;
                                else if(shade<1) shade=1;
                                shade=32-shade;
                                curshades=shadetable[shade];
#endif

                                pixheight=scale1*2;
                                upperedge=viewheight/2-scale1;

                                mask=1<<(slinex&3);
                                VGAMAPMASK(mask);
                                line=(word *)((byte *)shape + cmdptr[i]);
                               
                                while(*line)
                                {
                                        starty=(*(line+2))>>1;
                                        endy=(*line)>>1;
                                        newstart=(*(line+1));
                                        j=starty;
                                        ycnt=j*pixheight;
                                        screndy=(ycnt>>6)+upperedge;
                                        if(screndy<0) vmem=vbuf+(slinex>>2);
                                        else vmem=vbuf+screndy*80+(slinex>>2);
                                        for(;j<endy;j++)
                                        {
                                                scrstarty=screndy;
                                                ycnt+=pixheight;
                                                screndy=(ycnt>>6)+upperedge;
                                                if(scrstarty!=screndy && screndy>0)
                                                {
#ifdef SHADE_COUNT
                                                        col=curshades[((byte *)shape)[newstart+j]];
#else
                                                        col=((byte *)shape)[newstart+j];
#endif
                                                        if(scrstarty<0) scrstarty=0;
                                                        if(screndy>viewheight) screndy=viewheight,j=endy;
                                                       

                                                        while(scrstarty<screndy)
                                                        {
                                                                *vmem=col;
                                                                vmem+=80;
                                                                scrstarty++;
                                                        }
                                                }
                                        }
                                        line+=3;
                                }
                        }
                }
        }
}



void Scale3DShape(statobj_t *ob)
{
   fixed nx1,nx2,ny1,ny2;
        int viewx1,viewx2;
   long height1, height2;
   fixed diradd;

//
// the following values for "diradd" aren't optimized yet
// if you have problems with sprites being visible through wall edges
// where they shouldn't, you can try to adjust these values and
// the -1024 and +2048 in both "if" blocks
//

   if(ob->flags & FL_DIRFORWARD) diradd=0x7ff0+0x8000;
   else if(ob->flags & FL_DIRBACKWARD) diradd=-0x7ff0+0x8000;
   else diradd=0x8000;

   if(ob->flags & FL_DIREAST)
        {
      fixed gx1,gx2,gy,gxt1,gxt2,gyt;
//
// translate point to view centered coordinates
//
      gx1 = (((long)ob->tilex) << TILESHIFT)+0x8000-playx-0x8000L-1024;
      gx2 = gx1+0x10000L+2048;
      gy = (((long)ob->tiley) << TILESHIFT)+diradd-playy;

//
// calculate newx
//
      gxt1 = FixedMul(gx1,viewcos);
      gxt2 = FixedMul(gx2,viewcos);
      gyt = FixedMul(gy,viewsin);
      nx1 = gxt1-gyt-0x2000;
      nx2 = gxt2-gyt-0x2000;

//
// calculate newy
//
      gxt1 = FixedMul(gx1,viewsin);
      gxt2 = FixedMul(gx2,viewsin);
      gyt = FixedMul(gy,viewcos);
      ny1 = gyt+gxt1;
                ny2 = gyt+gxt2;
        }
   else
   {
      fixed gy1,gy2,gx,gyt1,gyt2,gxt;
//
// translate point to view centered coordinates
//
      gy1 = (((long)ob->tiley) << TILESHIFT)+0x8000-playy-0x8000L-1024;
      gy2 = gy1+0x10000L+2048;
      gx = (((long)ob->tilex) << TILESHIFT)+diradd-playx;

//
// calculate newx
//
      gxt = FixedMul(gx,viewcos);
      gyt1 = FixedMul(gy1,viewsin);
      gyt2 = FixedMul(gy2,viewsin);
      nx1 = gxt-gyt1-0x2000;
      nx2 = gxt-gyt2-0x2000;

//
// calculate newy
//
      gxt = FixedMul(gx,viewsin);
      gyt1 = FixedMul(gy1,viewcos);
      gyt2 = FixedMul(gy2,viewcos);
      ny1 = gyt1+gxt;
      ny2 = gyt2+gxt;
   }

//
// calculate perspective ratio
//
   if(nx1>=0 && nx1<=1792) nx1=1792;
   if(nx1<0 && nx1>=-1792) nx1=-1792;
   if(nx2>=0 && nx2<=1792) nx2=1792;
   if(nx2<0 && nx2>=-1792) nx2=-1792;

   viewx1=(int)(centerx+ny1*scale/nx1);
   viewx2=(int)(centerx+ny2*scale/nx2);

//
// calculate height (heightnumerator/(nx>>8)) (heightnumerator=0x36800)
//
    height1 = (short)(heightnumerator/(nx1>>8));
    height2 = (short)(heightnumerator/(nx2>>8));

   if(viewx2 < viewx1)
      {
      Scale3DShaper(viewx2,viewx1,ob->shapenum,(unsigned)height2,
         (unsigned)height1,ny2,ny1,nx2,nx1);
      }
   else
      {
      Scale3DShaper(viewx1,viewx2,ob->shapenum,(unsigned)height1,
         (unsigned)height2,ny1,ny2,nx1,nx2);
      }


}


Hope this helps someone,
the_fish
Anonymous
Guest



Last Visit:





PostPosted: Sat Feb 03, 2007 12:55 pm
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

*Sorry double posted*


Last edited by Anonymous on Sat Feb 03, 2007 1:00 pm; edited 1 time in total
Anonymous
Guest



Last Visit:





PostPosted: Sat Feb 03, 2007 12:59 pm
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

I added this tutorial to my code but i had a problem. First the 3d sprites weren`t 3d and rotated like any other sprite. So i changed this piece of code
::: CODE :::

         if (visptr < &vislist[MAXVISABLE-1]) // don't let it overflow

         {
            visptr->transsprite=NULL;

           visptr++;
         }

to this
::: CODE :::

         if (visptr < &vislist[MAXVISABLE-1]) // don't let it overflow

         {

           visptr++;
            visptr->transsprite=NULL;         
       }

Now I have two question.
1) Was this Ripper`s mistake or did I miss something
2) Once i did this(i also tried commenting the visptr->transsprite=NULL line) the actors in the game disappear when they are in certain states(ie. guard disappears while chasing but appears when killed). How can i fix this? This problem wasn`t there before i added the tutorial`s code.
Black Man
Registered User
Registered User


Joined: 19 May 2006
Last Visit: 09 Aug 2016

Topics: 8
Posts: 22

germany.gif

PostPosted: Fri Nov 23, 2007 11:55 pm
   Subject: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

How can i use DarkOne's sprite bug fix, when is use Rippers Removing the scalers tutorial?
Please Help me with this.

Blacky
KyleRTCW
DieHard Officer
DieHard Officer


Joined: 30 Jul 2003
Last Visit: 09 Nov 2017

Topics: 45
Posts: 510
Location: Ohio
usa.gif

PostPosted: Sun Nov 25, 2007 4:33 pm
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

It's already included in the tutorial...

Quote:
Update: At this point I'll insert DarkOne's sprite bug fix, so that you'll be able to use full width sprites.

Replace the ScaleShape and SimpleScaleShape functions with the following functions:


The fix is already implemented with these modified functions.

_________________
Steam: http://steamcommunity.com/id/stormx312
Dean
Moderator
<B>Moderator</B>


Joined: 10 Jan 2006
Last Visit: 23 Oct 2016

Topics: 52
Posts: 2187
Location: Australia
australia.gif

PostPosted: Fri Sep 26, 2008 2:35 pm
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

I'm trying to add this but I'm sure it's causing problems with other coding I have also added in WL_SCALE.C. Does anyone know what other tutorials have coding that is added or adjusted in this section so I can look at those to replace any required info I may have removed when replacing the ScaleShape and SimpleScaleShape functions? Thanks

_________________
The Wolfenstein 3d Blog
The Wolfenstein 3d Blog is now on Facebook!

"Strong minds discuss ideas, average minds discuss events, weak minds discuss people" - Socrates
Tricob
Moderator
<B>Moderator</B>


Joined: 14 Mar 2005
Last Visit: 15:26 ago.

Topics: 160
Posts: 8007
Location: Neo-traditions, Inc.
usa.gif

PostPosted: Fri Sep 26, 2008 7:35 pm
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Well, there's a 3D Sprites tutorial on Ripper's website, but the website keeps timing out on my PC right now ... Sad
Dean
Moderator
<B>Moderator</B>


Joined: 10 Jan 2006
Last Visit: 23 Oct 2016

Topics: 52
Posts: 2187
Location: Australia
australia.gif

PostPosted: Sat Sep 27, 2008 2:10 pm
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

I've added that as well. What I was asking was whether theres other coding that may have placed some code into those sections as I have just replaced the whole lot witht he directional sprites code. I'm concerned that I've affected something else that I've already coded.

_________________
The Wolfenstein 3d Blog
The Wolfenstein 3d Blog is now on Facebook!

"Strong minds discuss ideas, average minds discuss events, weak minds discuss people" - Socrates
Tricob
Moderator
<B>Moderator</B>


Joined: 14 Mar 2005
Last Visit: 15:26 ago.

Topics: 160
Posts: 8007
Location: Neo-traditions, Inc.
usa.gif

PostPosted: Sat Sep 27, 2008 8:43 pm
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

I'm not sure how the 3D Sprites code would affect other routines. What feature have you coded in that has had problems since you put in the 3D Sprites code?
Dean
Moderator
<B>Moderator</B>


Joined: 10 Jan 2006
Last Visit: 23 Oct 2016

Topics: 52
Posts: 2187
Location: Australia
australia.gif

PostPosted: Sun Sep 28, 2008 11:43 pm
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

It won't compile to be able to give me an exe to be able to test and see....

Anyway, like every other piece of coding I have tried recently I have just over ridden it with my back up files. There goes about 10 hours of coding and attempted fixes over the last week or so!

I give up I think for now, I might just put the code asaide and try again in another couple of months.

_________________
The Wolfenstein 3d Blog
The Wolfenstein 3d Blog is now on Facebook!

"Strong minds discuss ideas, average minds discuss events, weak minds discuss people" - Socrates
Tricob
Moderator
<B>Moderator</B>


Joined: 14 Mar 2005
Last Visit: 15:26 ago.

Topics: 160
Posts: 8007
Location: Neo-traditions, Inc.
usa.gif

PostPosted: Mon Sep 29, 2008 6:53 pm
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Dean wrote:
It won't compile to be able to give me an exe to be able to test and see...
What errors did it give you when you attempted to compile? Question
Dean
Moderator
<B>Moderator</B>


Joined: 10 Jan 2006
Last Visit: 23 Oct 2016

Topics: 52
Posts: 2187
Location: Australia
australia.gif

PostPosted: Tue Sep 30, 2008 1:03 am
   Subject: Re: [Code] Directional Sprites - Ripper
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Bottom of Posts

No idea, as I said I just replaced the files with my back ups. I looked at the code and tried to see what it was talking about but I couldn't even find anything. I checked the other tutorials I had used to put stuff in and none of them put stuff in this section.

Stuff it, I give up for now. Thanks anyway Tricob.


EDIT:

Well, I didn't let it get the better of me. I tried and tried again and eventually got everything working! Smile

Can someone please explian the line in the tutorial that says this though please;
'The last option you have is the position inside a map tile. The sprite can be in the middle or on one of two edges depending on whether fw (forward) or bw (backward) is used and of course which direction.'

The reason I ask is because my game crashes each time I walk past any of the directional sprites. I have so far put in a blocking n/s directional rail and a blocking e/w directional rail.
::: CODE :::
{SPR_STAT_62,bl_dir_south},             // Directional rail n/S
{SPR_STAT_62,bl_dir_east},              // Directional rail E/W

when I try to get into the room that they are in the first one I walk past is to either side with a wall on either end, like this;

WPW
DPD
WPW

W = Wall
D = Directional sprite
P = Path (blank area)

Do I need to change the type of directional sprite that I am using or do I need multiple ones for the same directional sprites depending on where I use them and if other directional sprites are touching them?

_________________
The Wolfenstein 3d Blog
The Wolfenstein 3d Blog is now on Facebook!

"Strong minds discuss ideas, average minds discuss events, weak minds discuss people" - Socrates
Display posts from previous:   
Post new topicReply to topic Time synchronized with the forum server time
DieHard Wolfers Forum Index -> Code Tutorials View Previous TopicRefresh this PageAdd Topic to your Browser FavoritesSearch ForumsPrint this TopicE-mail TopicGoto Page TopView Next Topic
Page 1 of 1
Jump to:  

Related topics
 Topics   Replies   Views   Last Post 
No new posts [Code] Add Text to Screen at Skill Level select - Chris
Author: Chris
3 2438 Tue Sep 28, 2010 6:59 pm
Tricob View latest post
No new posts [Code] Display Different Ammo Types on Statusbar-BrotherTank
Author: BrotherTank
1 2381 Fri Feb 11, 2005 9:18 pm
Zombie_Plan View latest post
No new posts [Code] Changing an Enemies Attack Strength - BrotherTank
Author: BrotherTank
0 1969 Tue Jan 27, 2004 10:29 am
BrotherTank View latest post
No new posts [Code] Changing Weapons -CheckWeaponChange- BrotherTank
Author: BrotherTank
2 2700 Sun Oct 26, 2003 1:21 am
Guest View latest post
No new posts [Help] Different Enemy Dying Frames/Views
Author: Guest
7 607 Tue Jul 29, 2003 3:00 pm
Codetech84 View latest post
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
   You cannot delete your posts in this forum
You cannot vote in polls in this forum


Copyright ©2003-2008 DieHard Wolfers
A Modified subBunker Theme by BrotherTank
Powered by phpBB © 2001, 2005 phpBB Group