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       

[Help] Convert This Routine to C++ - ASM Coders
Page 1 of 1
DieHard Wolfers Forum Index -> SDL Code Crackers 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: 2248
Location: Ontario
canada.gif

PostPosted: Fri Aug 01, 2008 8:27 pm
   Subject: [Help] Convert This Routine to C++ - ASM Coders
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Next PostGoto Bottom of Posts

::: CODE :::

void DrawSpan(int spanx, int spanwidth, int spanheight, byte far *src, boolean transparency)
{
  long     y, dy;
  int      y0, y1, y2;             // top wall edge, texel start pos & end pos
  int      v;                      // texture
  unsigned drawwidth, columnofs;   // for use with stupid VGA write mode
  byte     color;
#ifdef SHADING 
  byte far *colormap;   // source color
#endif

  dy=(long)spanheight<<10;          // step
  y0=(viewheight-spanheight)>>1;    // starting pos

// color shade level choose
#ifdef SHADING
  if(spec_lt) colormap=spec_lt;     // special lighttable
  else if(spanheight<viewheight && !isasprite) colormap=lt[spanheight>>2];   // from shade table
  else colormap=lighttable[0];      // very close: first color
#endif
  while(spanwidth>0)
  {
    y=0;
    y2=y0;
    columnofs=spanx>>2;             // screen memory offset that comes from x coord
/*
** the following code makes clever VGA write mode switching
** would not be needed on any linerar video buffer
*/
    if(spanwidth==1)      // only 1px left, don't do any extra work, just draw it!
    {
      byte p=spanx&3;
      asm {cli;mov dx,0x3C4;mov ax,0x0102;mov cl,p;shl ah,cl;out dx,ax;sti;}
      drawwidth=1;
      spanwidth=0;
    }
    else switch(spanx&3)
    {
      case 0:                               // run of the quads
        drawwidth=spanwidth>>2;
        if(drawwidth)
        {                                   // xxxx
          asm {cli;mov dx,0x3C4;mov al,2;mov ah,15;out dx,ax;sti;};
          spanwidth&=3;
          spanx+=drawwidth<<2;
        }
        else                                // last bits
        {
          drawwidth=1;
          switch(spanwidth)
          {
            case 2: asm {cli;mov dx,0x3C4;mov al,2;mov ah,3;out dx,ax;sti;};  break;  // xx..
            case 3: asm {cli;mov dx,0x3C4;mov al,2;mov ah,7;out dx,ax;sti;};  break;  // xxx.
          }
          spanwidth=0;
        }
        break;
      case 1:                               // first bits
        drawwidth=1;
        if(spanwidth>=3)
        {
          asm {cli;mov dx,0x3C4;mov al,2;mov ah,14;out dx,ax;sti;};   // .xxx
          spanwidth-=3;
          spanx+=3;
        }
        else
        {
          asm {cli;mov dx,0x3C4;mov al,2;mov ah,6;out dx,ax;sti;};   // .xx.
          spanwidth-=2;
          spanx+=2;
        }
        break;
      case 2:
        drawwidth=1;
        asm {cli;mov dx,0x3C4;mov al,2;mov ah,12;out dx,ax;sti;};    // ..xx
        spanwidth-=2;
        spanx+=2;
        break;
      case 3:
        drawwidth=1;
        asm {cli;mov dx,0x3C4;mov al,2;mov ah,8;out dx,ax;sti;};    // ...x
        spanwidth-=1;
        spanx++;
        break;
    }

    for(v=0; v<RESVAL9; v++)
    {
      y1=y2;
      y+=dy;
      y2=(y>>RESVAL10)+y0;

      if(y1>=viewheight) break;               // off the screen
      if(y1==y2 || y2<0) continue;            // nothing to draw
      if(y1<0) y1=0;                          // not into the view area

      color=src[v];
      if(color==0xFF)                         // transparent texel 255 in the wolf palette
      {
        if(transparency) continue;
        else color=0x00;                      // substitute with black
      }
      else if(transparency==2) color=(US_RndT()&7)+24; // spectre (translucency effect) shades of grey
#ifdef SHADING
      if (gamestate.shading) color = colormap[color];
#endif
      asm mov es,[screenseg]
      _DI=bufferofs+ylookup[y1]+columnofs;
      asm mov al,[color]
      asm mov dx,[drawwidth]
      for(; y1<y2 && y1<viewheight; y1++)
      {
        asm { mov cx,dx; rep stosb; sub di,dx; add di,80; }
      }
    }
  }
}


This is the main draw routine for the Raycastor Convert.
I sort of understand what the ASM is doing but I need someone to convert it to C++ because while I understand a little, that little understanding is just enough to be dangerous..

Greg
BrotherTank
Ripper
Code Master - Developer
Code Master - Developer


Joined: 15 Mar 2003
Last Visit: 30 Sep 2008

Topics: 21
Posts: 527
Location: Germany
blank.gif

PostPosted: Sun Aug 10, 2008 6:58 am
   Subject: Re: [Help] Convert This Routine to C++ - ASM Coders
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Well, I guess you want this to be converted to Wolf4SDL code. The routine gets MUCH smaller for SDL as we don't have to work with the ModeX graphics mode (VGAMAPMASK etc.):

::: CODE :::
void DrawSpan(int spanx, int spanwidth, int spanheight, byte *src, boolean transparency)
{
  long     y, dy;
  int      y0, y1, y2;             // top wall edge, texel start pos & end pos
  int      v;                      // texture
  byte     color;
#ifdef SHADING 
  byte    *colormap;   // source color
#endif
  byte    *vptr;

  dy=(long)spanheight<<10;          // step
  y0=(viewheight-spanheight)>>1;    // starting pos

#ifdef SHADING
  // color shade level choose
  if(spec_lt) colormap=spec_lt;     // special lighttable
  else if(spanheight<viewheight && !isasprite) colormap=lt[spanheight>>2];   // from shade table
  else colormap=lighttable[0];      // very close: first color
#endif

  y=0;
  y2=y0;

  for(v=0; v<RESVAL9; v++)
  {
    y1=y2;
    y+=dy;
    y2=(y>>RESVAL10)+y0;

    if(y1>=viewheight) break;               // off the screen
    if(y1==y2 || y2<0) continue;            // nothing to draw
    if(y1<0) y1=0;                          // not into the view area
    if(y2>=viewheight) y2=viewheight;       // clip lower boundary

    color=src[v];
    if(color==0xFF)                         // transparent texel 255 in the wolf palette
    {
      if(transparency) continue;
      else color=0x00;                      // substitute with black
    }
    else if(transparency==2) color=(US_RndT()&7)+24; // spectre (translucency effect) shades of grey
#ifdef SHADING
    if (gamestate.shading) color = colormap[color];
#endif

    vptr = vbuf + y1 * vbufPitch + spanx;
    for(; y1<y2; y1++, vptr += vbufPitch)
    {
      memset(vptr, spanwidth, color);
    }
  }
}

The code wasn't tested, as I don't have the rest of your code, but it should work.
Hope that helps
Ripper

_________________
Life is an awful game, but the graphics resolution rocks ;D
BrotherTank
Forum Administrator
<B>Forum Administrator</B>


Joined: 01 Mar 2003
Last Visit: 13 Sep 2017

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

PostPosted: Sun Aug 10, 2008 8:54 pm
   Subject: Re: [Help] Convert This Routine to C++ - ASM Coders
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

A big thanks Ripper....

I'll Let you know how it works out. All the other parts of the Raycastor port from Darkone's engine are just plain C+ programming... and it was this - the only drawing routine for both Walls and Sprites, that was stopping me from converting the raycastor over for use in SDL.

I'm a bit busy during this week, but I will hopefully have it installed and tested by next weekend. And when I have it all working (fingers crossed), I'll put together a small little tutorial for coverting the raycastor as I did with the original 16 bit code...

Once again... A Big thanks... I wish that I knew ASM.... lol...

Greg
BrotherTank
Ripper
Code Master - Developer
Code Master - Developer


Joined: 15 Mar 2003
Last Visit: 30 Sep 2008

Topics: 21
Posts: 527
Location: Germany
blank.gif

PostPosted: Mon Aug 11, 2008 3:36 am
   Subject: Re: [Help] Convert This Routine to C++ - ASM Coders
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

You are welcome ;D

I'm looking forward to see your results!

About the ASM: The most important instruction of the original return was "rep stosb". This instruction sets cx bytes starting at the address es:di to the value of al. After this instruction di will be increased by cx and cx will be zero. By subtracting the drawwidth and adding 80 to di, the next iteration of the for loop will paint the next row of the span.
As you can see I replaced the "rep stosb" asm part by the standard C function "memset", which gets inlined by all decent compilers to produce very fast and portable code, and some pointer arithmetic (vptr).

_________________
Life is an awful game, but the graphics resolution rocks ;D
Chris
DieHard Wolfer
DieHard Wolfer


Joined: 11 Mar 2003
Last Visit: 16 Jul 2019

Topics: 56
Posts: 2234
Location: Canada
blank.gif

PostPosted: Thu Feb 14, 2019 2:53 pm
   Subject: Re: [Help] Convert This Routine to C++ - ASM Coders
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Ripper wrote:
I'm looking forward to see your results!

AryanWolf3D got your code to work, the only issue he said I believe was that the memset line had "color" for the size. Very Happy
Aryan_Wolf3D
DieHard Guard
DieHard Guard


Joined: 21 Jul 2011
Last Visit: 21 Jul 2019

Topics: 6
Posts: 254

blank.gif

PostPosted: Thu Feb 14, 2019 3:02 pm
   Subject: Re: [Help] Convert This Routine to C++ - ASM Coders
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Bottom of Posts

Yeah, that's correct, just flip "spanwidth" around with "color" in the memset call and it works. An even better idea is to get rid of the "spanwidth" stuff altogether (because the optimisation is pointless in Wolf4SDL), and just put "*vptr = color".

Hopefully this will save anyone brave enough to try getting this to work from some pain...

_________________
"Way too many #ifdefs in the code!" - John Carmack
Display posts from previous:   
Post new topicReply to topic Time synchronized with the forum server time
DieHard Wolfers Forum Index -> SDL Code Crackers 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 [help] Adding teleporters in wolf4sdl
Author: Mortimer
35 14619 Fri May 26, 2017 8:19 am
Military View latest post
No new posts [WOLF4SDL Help] Blake Stone Style doors
Author: Haasboy
3 3710 Sun Jul 20, 2008 7:56 am
Haasboy View latest post
No new posts [Help] Problem with Checkweaponchange function (wolf4sdl)
Author: Mortimer
4 3979 Sat May 17, 2008 11:26 am
Mortimer View latest post
No new posts [help] Wolf4sdl's implemented tutorials
Author: Mortimer
6 4240 Tue May 06, 2008 1:15 pm
Ripper View latest post
No new posts [SDL] Apply 2nd ScaleFactor to selected (hi-res) vga gfx
Author: Andy_Nonymous
9 5733 Sun Apr 27, 2008 2:30 am
AlumiuN 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