DarkOneТs Wolf3D source tutorial ╣3.

Knee-Deep in the Brick

 

The purpose of this tutorial is to make textured floor/ceiling in Wolf3D. This feature will give your engine the best boost in visual quality, so letТs get to work:

 

WeТll work in WL_DRAW.C file:

 

First find the following line:

 

unsignedа wallheight[MAXVIEWWIDTH;

 

And modify it like this:

 

unsignedа wallheight[MAXVIEWWIDTH], min_wallheight;

 

Then add following lines to the end of CalcHeight function:

 

intа CalcHeight (void)

{

<..>

<.here is original CalcHeight code.>

<..>

 

// update min_wallheight

а asm mov bx,[min_wallheight]

а asm cmp ax,bx

а asm jae noupdate:

а asm mov [min_wallheight],ax

noupdate:;

}

 

Then add the following macro declaration just before the start of vgaCeiling array declaration:

 

#define USE_TEX(page) (0x0000|(page))

 

/*

** use USE_TEX(n) to use floor/ceiling textures for given level

** n should be 1..255 !!!

** it is MAP-ID (from FloEdit). First texture goes to floor, second to ceiling

*/

 

unsigned vgaCeiling[]=

 

Now we are about to write the main texturing code: add this function just after vgaCeiling array declaration:

 

// ------------------------- * Textured flats * -------------------------

 

/*

** Draw Textured Floor/Ceiling

*/

void DrawFlats(unsigned tex_f, unsigned tex_c)

{

а int x, y, y0, halfheight;

а unsigned top_offset0, bot_offset0, top_offset, bot_offset;

а unsigned top_add, bot_add;

а byte p, color;

а byte far *src_bot, far *src_top;

 

а fixed dist;ааааааааааа // distance to row projection

а fixed tex_step;ааааааа // global step per one screen pixel

а fixed gu, gv, du, dv; // global texture coordinates

а int u, v;ааааааааааааа // local texture coordinates

 

// ------ * prepare * --------

а halfheight=viewheight>>1;

а y0=min_wallheight>>3;ааааа // starting y value

а if(y0>halfheight) return;а // view obscued by walls

а if(y0==0) y0=1;аааааааааа // don't let division by zero

а top_offset0=80*(halfheight-y0-1);а // and will decrease by 80 each row

а bot_offset0=80*(halfheight+y0);а // and will increase by 80 each row

 

а src_bot=PM_GetPage(tex_f); // load floor texture

а src_top=PM_GetPage(tex_c); // load ceiling texture

 

// draw horizontal lines

а for(p=0; p<4; p++)

а {

ааа asm mov ax,0x0102

ааа asm mov cl,[p]

ааа asm shl ah,cl

ааа asm mov dx,0x3c4

ааа asm out dx,ax

 

ааа for(y=y0, top_offset=top_offset0, bot_offset=bot_offset0; y<halfheight; y++, top_offset-=80, bot_offset+=80)

ааа {

ааааа dist=(heightnumerator/y)<<5;

 

ааааа gu= viewx+FixedByFrac(dist, viewcos);

ааааа gv=-viewy+FixedByFrac(dist, viewsin);

 

ааааа tex_step=(dist<<8)/viewwidth/175;

 

ааааа du= FixedByFrac(tex_step, viewsin);

ааааа dv=-FixedByFrac(tex_step, viewcos);

 

ааааа gu-=((viewwidth>>1)-p)*du;

ааааа gv-=((viewwidth>>1)-p)*dv; // starting point (leftmost)

 

ааааа du<<=2; // 4pix step

ааааа dv<<=2;

 

ааааа for(x=p, top_add=top_offset, bot_add=bot_offset; x<viewwidth; x+=4, top_add++, bot_add++)

ааааа {

ааааааа if(wallheight[x]>>3<=y)

ааааааа {

ааааааааа u=(gu>>10)&63; v=(gv>>10)&63;

 

ааааааааа color=*(src_top+((63-u)<<6)+(63-v));

 

// draw top pixel using [color]

ааааааааа asm mov es,[screenseg]

ааааааааа asm mov di,[bufferofs]

ааааааааа asm add di,[top_add]

а

ааааааааа asm mov al,[color]

ааааааааа asm mov es:[di],al

 

ааааааааа color=*(src_bot+(u<<6)+(63-v));

 

// draw bottom pixel using [color]

ааааааааа asm mov es,[screenseg]

ааааааааа asm mov di,[bufferofs]

ааааааааа asm add di,[bot_add]

а

ааааааааа asm mov al,[color]

ааааааааа asm mov es:[di],al

ааааааа }

ааааааа gu+=du; gv+=dv;

ааааа }

ааа }

а }

}

 

Be careful with it, itТs big and itТs easy to miss something. After that change VGAClearScreen like this:

 

void VGAClearScreen(unsigned ceiling)

{

ааа //

ааа // clear the screen

ааа //

 

As you see IТve removed ceiling variable from the function and added a parameter with the same name.

The last thing we will modify is ThreeDRefresh function:

 

void ThreeDRefresh (void)

{

ааа int tracedir;

ааа unsigned ceiling;

ааа boolean flats;

 

<..>

 

//

// follow the walls from there to the right, drawwing as we go

//

 

ааа ceiling=vgaCeiling[gamestate.episode*10+mapon];

 

ааа if((ceiling>>8)==(ceiling&0xFF))

ааа {

ааааааааа VGAClearScreen(ceiling);

ааааааааа flats=false;

ааа }

ааа else

ааа {

ааааааааа flats=true;

ааааааааа ceiling=((ceiling&0xFF)-1)<<1;

ааа }

 

ааа WallRefresh();

 

ааа if(flats)

ааааааааа DrawFlats(ceiling, ceiling+1); // draw textured floor/ceiling

 

Ok, enough coding, letТs learn how to use this feature. First you should find a pair of images: one for floor, one for ceiling texture. They should look like texture, of course this is not a must, but it would look silly. I selected the following images:

 

а

 

Then I used something called like F*Edit to import them to my data files. I used indexes 62 and 63 (note that first index must be even and second index must be equal to first plus 1. This would make MAP-ID the same for both of them!), and remembered MAP-ID, 32 in this case.

Then IТve chosen a level(s) to be textured using these textures (for simplicity it would be e1m1).

So I modified vgaCeiling array like that:

 

unsigned vgaCeiling[]=

{

#ifndef SPEAR

аUSE_TEX(32),0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0xbfbf,

а0x4e4e,0x4e4e,0x4e4e,0x1d1d,0x8d8d,0x4e4e,0x1d1d,0x2d2d,0x1d1d,0x8d8d,

а0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x2d2d,0xdddd,0x1d1d,0x1d1d,0x9898,

 

а0x1d1d,0x9d9d,0x2d2d,0xdddd,0xdddd,0x9d9d,0x2d2d,0x4d4d,0x1d1d,0xdddd,

а0x7d7d,0x1d1d,0x2d2d,0x2d2d,0xdddd,0xd7d7,0x1d1d,0x1d1d,0x1d1d,0x2d2d,

а0x1d1d,0x1d1d,0x1d1d,0x1d1d,0xdddd,0xdddd,0x7d7d,0xdddd,0xdddd,0xdddd

#else

а0x6f6f,0x4f4f,0x1d1d,0xdede,0xdfdf,0x2e2e,0x7f7f,0x9e9e,0xaeae,0x7f7f,

а0x1d1d,0xdede,0xdfdf,0xdede,0xdfdf,0xdede,0xe1e1,0xdcdc,0x2e2e,0x1d1d,0xdcdc

#endif

};

 

Note that I used MAP-ID, I remembered!

ThatТs all. IТve built .exe and started it. Here is a result:

 

 

Voila! ThatТs it!

 

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