Wolf3d Haven Forum

Please log in or register. Smile
Wolf3d Haven Forum

A friendly Wolfenstein 3D community, about Wolfenstein 3D, the game that gave birth to first person shooters...


    The Final Request! Urgent!

    Share

    Imed
    Can I Play, Daddy?
    Can I Play, Daddy?

    Number of posts : 32
    Age : 25
    Registration date : 2013-10-26

    The Final Request! Urgent!

    Post by Imed on Sat Mar 08, 2014 11:03 am

    Hello everybody!

    We have in our mod new and diferents types of 3d sprites, but we have a little problem adding those "new 3d sprites" without affect the original ones.

    This is the code of the original, the wl_dir3dspr.cpp file:


    #include "version.h"

    #ifdef USE_DIR3DSPR
    #include "wl_def.h"
    #include "wl_shade.h"

    // Define directional 3d sprites in wl_act1.cpp (there are two examples)
    // Make sure you have according entries in ScanInfoPlane in wl_game.cpp.


    void Scale3DShaper(int x1, int x2, int shapenum, uint32_t flags, fixed ny1, fixed ny2,
                       fixed nx1, fixed nx2, byte *vbuf, unsigned vbufPitch)
    {
        t_compshape *shape;
        unsigned scale1,starty,endy;
        word *cmdptr;
        byte *line;
        byte *vmem;
        int dx,len,i,newstart,ycnt,pixheight,screndy,upperedge,scrstarty;
        unsigned j;
        fixed height,dheight,height1,height2;
        int xpos[TEXTURESIZE+1];
        int slinex;
        fixed dxx=(ny2-ny1)<<8,dzz=(nx2-nx1)<<8;
        fixed dxa=0,dza=0;
        byte col;

        shape = (t_compshape *) PM_GetSprite(shapenum);

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

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

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

        xpos[0]=(int)((ny1+(dxa>>Cool)*scale/(nx1+(dza>>Cool)+centerx);
        height1 = heightnumerator/((nx1+(dza>>Cool)>>Cool;
        height=(((fixed)height1)<<12)+2048;

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

        height2 = heightnumerator/((nx1+(dza>>Cool)>>Cool;
        dheight=(((fixed)height2-(fixed)height1)<<12)/(fixed)dx;

        cmdptr = (word *) shape->dataofs;

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

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

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

                if(wallheight[slinex]<(height>>12) && scale1 /*&& scale1<=maxscale*/)
                {
    #ifdef USE_SHADING
                    byte *curshades;
                    if(flags & FL_FULLBRIGHT)
                        curshades = shadetable[0];
                    else
                        curshades = shadetable[GetShade(scale1<<3)];
    #endif

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

                    line=(byte *)shape + cmdptr[i];

                    while((endy = READWORD(line)) != 0)
                    {
                        endy >>= 1;
                        newstart = READWORD(line);
                        starty = READWORD(line) >> 1;
                        j=starty;
                        ycnt=j*pixheight;
                        screndy=(ycnt>>6)+upperedge;
                        if(screndy<0) vmem=vbuf+slinex;
                        else vmem=vbuf+screndy*vbufPitch+slinex;
                        for(;j                    {
                            scrstarty=screndy;
                            ycnt+=pixheight;
                            screndy=(ycnt>>6)+upperedge;
                            if(scrstarty!=screndy && screndy>0)
                            {
    #ifdef USE_SHADING
                                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                            {
                                    *vmem=col;
                                    vmem+=vbufPitch;
                                    scrstarty++;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    void Scale3DShape(byte *vbuf, unsigned vbufPitch, statobj_t *ob)
    {
        fixed nx1,nx2,ny1,ny2;
        int viewx1,viewx2;
        fixed diradd;
        fixed playx = viewx;
        fixed playy = viewy;

        //
        // 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 SIZEADD
        //

    #define SIZEADD 1024

        switch(ob->flags & FL_DIR_POS_MASK)
        {
            case FL_DIR_POS_FW: diradd=0x7ff0+0x8000; break;
            case FL_DIR_POS_BW: diradd=-0x7ff0+0x8000; break;
            case FL_DIR_POS_MID: diradd=0x8000; break;
            default:
                Quit("Unknown directional 3d sprite position (shapenum = %i)", ob->shapenum);
        }

        if(ob->flags & FL_DIR_VERT_FLAG) // vertical dir 3d sprite
        {
            fixed gy1,gy2,gx,gyt1,gyt2,gxt;
            //
            // translate point to view centered coordinates
            //
            gy1 = (((long)ob->tiley) << TILESHIFT)+0x8000-playy-0x8000L-SIZEADD;
            gy2 = gy1+0x10000L+2*SIZEADD;
            gx = (((long)ob->tilex) << TILESHIFT)+diradd-playx;

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

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

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

            //
            // calculate newy
            //
            gxt1 = FixedMul(gx1,viewsin);
            gxt2 = FixedMul(gx2,viewsin);
            gyt = FixedMul(gy,viewcos);
            ny1 = gyt+gxt1;
            ny2 = gyt+gxt2;
        }

        if(nx1 < 0 || nx2 < 0) return; // TODO: Clip on viewplane

        //
        // 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);


        if(viewx2 < viewx1)
        {
            Scale3DShaper(viewx2,viewx1,ob->shapenum,ob->flags,ny2,ny1,nx2,nx1,vbuf,vbufPitch);
        }
        else
        {
            Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);
        }
    }

    #endif

    Our new "3dsprites" are different in only two parts :

    This:

    if(wallheight[slinex]<(height>>12) && scale1 /*&& scale1<=maxscale*/)

    and this:

    if(viewx2 < viewx1)
        {
            Scale3DShaper(viewx2,viewx1,ob->shapenum,ob->flags,ny2,ny1,nx2,nx1,vbuf,vbufPitch);
        }
        else
        {
            Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);
        }

    Obviously, if we put our modified functions, the original 3dsprites, doesnt work anymore.
    We tried to solve this issue during a month, we are not good at coding ;( .

    So, how can i have "modified 3dsprites" and "normal 3dsprites" without conflicts...?
    Is possible to have 2 wl_dir3dspr.cpp (with different names, of course) in the same project?
    one i keep original and the other with my modified version of 3dsprites?

    Here an example:
    We have a new 3d sprite with only one side visible, but for that we need to modify this funtion:

    if(viewx2 < viewx1)
    {
    }

    Doing that directly to the wl_dir3dspr.cpp, of course, affects all the 3dsprites, We dont want that!
    We need them separately. The same thing happens with other type of 3dsprite we have, changing this:
    if(wallheight[slinex]<(height>>12) && scale1 /*&& scale1<=maxscale*/)

    So we need those two parts separately for the new 3dsprites, i thing.
    How can we re-arrange the code to make this thing work..

    I hope you understand me, i dont speak english so sorry if and not clear enough.


    Thanks in advance to everybody in this awesome site. We promise to write a full tutorial of all this
    when our mod is finish (We are almost there Smile).

    Mega Luigi
    Bring em' On!
    Bring em' On!

    Number of posts : 128
    Age : 13
    Registration date : 2012-11-01

    Re: The Final Request! Urgent!

    Post by Mega Luigi on Sun Mar 09, 2014 10:01 am

    Provided I understood what you wanna do, I think there is a simple solution, although maybe not the most elegant one. 

    If you look in the parameters of each function you mentioned, you will see the first one has "int shapenum" and the second one has "statobj_t *ob". Shapenum is actually the "name" of the sprite you define right there in wl_def.h and use in wl_act1.cpp, so you can use that to decide which objects are going to be affected by your changes.

    For example, the ones you want to be visible from one side only:


    Code:
    if (ob->shapenum == MYONESIDEVISIBLEOBJECT1 || ob->shapenum == MYONESIDEVISIBLEOBJECT2)
    {  
       if(viewx2 < viewx1)

          {

          }
      
       else

        {

            Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);   
       }
    }

    else
    {
        if(viewx2 < viewx1)


           {


            Scale3DShaper(viewx2,viewx1,ob->shapenum,ob->flags,ny2,ny1,nx2,nx1,vbuf,vbufPitch);


           }


        else


           {


            Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);


           }
    }




      And you can do that for as many different sprites as you want by inserting them like I did in the example. You can also do a similar thing for the other function, just keep in mind that you will have to use "if (shapenum == xxx)" instead of "if(ob->shapenum == xxx)" since the parameters are not the same. Also, I didn't test any of this  Cool , but I don't see any reason for it not to work.

    By the way, I had a hard time typing this thing. After I inserted the first "code" up there, every key I pressed would be inserted in a new code thing. That was awful.

    Imed
    Can I Play, Daddy?
    Can I Play, Daddy?

    Number of posts : 32
    Age : 25
    Registration date : 2013-10-26

    Re: The Final Request! Urgent!

    Post by Imed on Tue Mar 11, 2014 7:40 pm

    @Mega Luigi wrote:Provided I understood what you wanna do, I think there is a simple solution, although maybe not the most elegant one. 

    If you look in the parameters of each function you mentioned, you will see the first one has "int shapenum" and the second one has "statobj_t *ob". Shapenum is actually the "name" of the sprite you define right there in wl_def.h and use in wl_act1.cpp, so you can use that to decide which objects are going to be affected by your changes.

    For example, the ones you want to be visible from one side only:


    Code:
    if (ob->shapenum == MYONESIDEVISIBLEOBJECT1 || ob->shapenum == MYONESIDEVISIBLEOBJECT2)
    {  
       if(viewx2 < viewx1)

          {

          }
      
       else

        {

            Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);   
       }
    }

    else
    {
        if(viewx2 < viewx1)


           {


            Scale3DShaper(viewx2,viewx1,ob->shapenum,ob->flags,ny2,ny1,nx2,nx1,vbuf,vbufPitch);


           }


        else


           {


            Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);


           }
    }




      And you can do that for as many different sprites as you want by inserting them like I did in the example. You can also do a similar thing for the other function, just keep in mind that you will have to use "if (shapenum == xxx)" instead of "if(ob->shapenum == xxx)" since the parameters are not the same. Also, I didn't test any of this  Cool , but I don't see any reason for it not to work.

    By the way, I had a hard time typing this thing. After I inserted the first "code" up there, every key I pressed would be inserted in a new code thing. That was awful.


    Oh, thank you. That would be a good place to start.!!!  cheers

    I will try this tomorrow!! yeah!

    Mega Luigi
    Bring em' On!
    Bring em' On!

    Number of posts : 128
    Age : 13
    Registration date : 2012-11-01

    Re: The Final Request! Urgent!

    Post by Mega Luigi on Wed Mar 12, 2014 12:05 pm

    No problem  Cool 

    Just tell me if worked, once you try it.

    mmed
    Don't Hurt Me!
    Don't Hurt Me!

    Male
    Number of posts : 52
    Age : 22
    Registration date : 2012-07-25

    Re: The Final Request! Urgent!

    Post by mmed on Fri Mar 14, 2014 10:51 am

    @Mega Luigi wrote:Provided I understood what you wanna do, I think there is a simple solution, although maybe not the most elegant one. 

    If you look in the parameters of each function you mentioned, you will see the first one has "int shapenum" and the second one has "statobj_t *ob". Shapenum is actually the "name" of the sprite you define right there in wl_def.h and use in wl_act1.cpp, so you can use that to decide which objects are going to be affected by your changes.

    For example, the ones you want to be visible from one side only:


    Code:
    if (ob->shapenum == MYONESIDEVISIBLEOBJECT1 || ob->shapenum == MYONESIDEVISIBLEOBJECT2)
    {  
       if(viewx2 < viewx1)

          {

          }
      
       else

        {

            Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);   
       }
    }

    else
    {
        if(viewx2 < viewx1)


           {


            Scale3DShaper(viewx2,viewx1,ob->shapenum,ob->flags,ny2,ny1,nx2,nx1,vbuf,vbufPitch);


           }


        else


           {


            Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);


           }
    }




      And you can do that for as many different sprites as you want by inserting them like I did in the example. You can also do a similar thing for the other function, just keep in mind that you will have to use "if (shapenum == xxx)" instead of "if(ob->shapenum == xxx)" since the parameters are not the same. Also, I didn't test any of this  Cool , but I don't see any reason for it not to work.

    By the way, I had a hard time typing this thing. After I inserted the first "code" up there, every key I pressed would be inserted in a new code thing. That was awful.

    I've tried and it works!

    I can use as "ob-> flags" instead of "ob-> shapenum" ?

    and add 2 object flag:    FL_SIDE1 and FL_SIDE2

    but I do not understand these values

    FL_AMBUSH           = 0x00000040,
    FL_NONMARK          = 0x00000080,
    FL_FULLBRIGHT       = 0x00000100,


    I have already used 0x00001000


    is it possible?

    Mega Luigi
    Bring em' On!
    Bring em' On!

    Number of posts : 128
    Age : 13
    Registration date : 2012-11-01

    Re: The Final Request! Urgent!

    Post by Mega Luigi on Fri Mar 14, 2014 5:59 pm

    Cool  Cool 

    Yeah, I think you can. Just remember that in the first function you must use only "flags", since it doesn't have a object as parameter.

    Those values are like that because they have only one bit in one and the rest in zero (that might not be true for some of the flags used by Ripper in his directional 3d sprites code). That enables you to sum them.
    For example:

    FL_BONUS = 0x00000002 = 0000 0000 0000 0010
    FL_ATTACKMODE = 0x00000010 = 0000 0000 0001 0000

    If you wanted something to have both FL_BONUS and FL_ATTACKMODE (not that this makes any sense at all), you would have 0000 0000 0001 0010.

    In other words, you could use 0x00002000 since it has only one bit in one and the rest in zero, for example.

    Sponsored content

    Re: The Final Request! Urgent!

    Post by Sponsored content Today at 11:35 am


      Current date/time is Fri Sep 30, 2016 11:35 am