how to get tile-based shading ála the_fish to work in your Wolf3D game...
- Spoiler:
If you use this code in your game, remember to credit Adam Biser,
AlumiuN, the_fish and WSJ... Also I haven't got the 4th plane working yet
but I am posting this tutorial anyway so if someone manages to get it
work before I do, s/he can complete this tutorial.
Also this tutorial is really long and complicated so here is the full source (Wolf4SDL v1.7)
containing the necessary coding changes (not including the pickable flashlight).
Oh, and you shouldn't use advanced shading without textured floor/ceiling as the flashlights light
isn't working that great with solid color floor/ceiling.
Anyway... Let's begins...
First open version.h and search for this line:
- Code:
#define USE_SHADING // Enables shading support (see wl_shade.cpp)
- Code:
#define USE_ADVSHADES // Enables advanced shading
//#define USE_4THPLANE // Enables 4th plane for shading (not working yet)
Then open wl_def.h and search for "gamestate structure"...
Add these lines to that struct:
- Code:
#ifdef USE_ADVSHADES
bool flashlight;
#endif
to the end of that struct (just below "struct statestruct *next;"):
- Code:
#ifdef USE_SHADING
boolean fullbright; // WSJs lightning effects...
#endif
- Code:
#ifdef USE_SHADING
void T_LightEnemy(objtype *ob);
#endif
- Code:
#ifdef USE_DIR3DSPR
void Scale3DShape(byte *vbuf, unsigned vbufPitch, statobj_t *ob);
#endif
- Code:
#ifdef USE_DIR3DSPR
void Scale3DShape(byte *vbuf, unsigned vbufPitch, statobj_t *ob
#ifdef USE_ADVSHADES
,int tx = 0, int ty = 0, int fx = 0, int fy = 0);
#endif
);
#endif
- Code:
#ifdef USE_SHADING
extern int lightMap[MAPSIZE][MAPSIZE];
#endif
When you have done that, open wl_state.cpp search
for "MoveObj (objtype *ob" (should be near the beginning of the file) and
add these lines:
- Code:
#ifdef USE_SHADING
void T_LightEnemy(objtype *ob);
#endif
- Code:
/*
=======================
=
= T_LightEnemy
=
= Check if actor walked under lamp and then
= try illuminate actor...
=
= NOTE: This is bit unnecessary with advanced shading
= as the actors are shaded like objects.
=
=======================
*/
#ifdef USE_SHADING
void T_LightEnemy(objtype *ob)
{ // Check for lightsources in actors tile:
if(lightMap[ob->tilex][ob->tiley]>240)
ob->state->fullbright = true;
else
ob->state->fullbright = false;
}
#endif
these line at the beginning of that function:
- Code:
#ifdef USE_SHADING
T_LightEnemy(ob);
#endif
these lines to make the corpse light up if underneath a light source:
- Code:
#ifdef USE_SHADING
T_LightEnemy(ob); //Light the corpse up?
#endif
To make the enemies lit up when shooting, open wl_act2.cpp
and search for "SPR_GRD_SHOOT3"... You should see something like this:
- Code:
statetype s_grdshoot3 = {false,SPR_GRD_SHOOT3,20,NULL,NULL,&s_grdchase1};
- Code:
#ifdef USE_SHADING
statetype s_grdshoot3 = {false,SPR_GRD_SHOOT3,20,NULL,NULL,&s_grdchase1,true};
#else
statetype s_grdshoot3 = {false,SPR_GRD_SHOOT3,20,NULL,NULL,&s_grdchase1};
#endif
and make similar changes... Also remember to go through the bosses and projectiles
(prefer the file in the packaged source for all changes).
Close the wl_act2.cpp...
Now when that is done, open wl_game.cpp and search for "died"...
In the died function, search for this line:
- Code:
gamestate.ammo = STARTAMMO;
- Code:
#ifdef USE_ADVSHADES
gamestate.flashlight = false; //Reset flashlight
#endif
- Code:
gamestate.keys = 0;
- Code:
#ifdef USE_ADVSHADES
gamestate.flashlight = false; //Reset flashlight
#endif
Now open wl_main.cpp and search for "new game" and
in that function search for this line:
- Code:
gamestate.ammo = STARTAMMO;
- Code:
#ifdef USE_ADVSHADES
gamestate.flashlight = false; //Reset flashlight
#endif
Open wl_play.cpp and scroll to "GLOBAL VARIABLES"...
Add these lines under "madenoise":
- Code:
#ifdef USE_SHADING
int lightMap[MAPSIZE][MAPSIZE];
#endif
- Code:
#ifdef USE_ADVSHADES
//
// Flashlight
//
if(Keyboard[sc_Z])
{ gamestate.flashlight ^= 1;
Keyboard[sc_Z]=false;
return;
}
#endif
To prevent player from assigning some other function for the 'Z'-key,
open wl_menu.cpp and search for "case KEYBOARDBTNS:" (approx. line 2335).
The change this line:
- Code:
if (LastScan && LastScan != sc_Escape)
- Code:
#ifdef USE_ADVSHADES
if (LastScan && (LastScan != sc_Escape || LastScan != sc_Z))
#else
if (LastScan && LastScan != sc_Escape)
#endif
Now we are done in wl_menu.cpp...
Okay... This is the part where things are starting to get interesting...
Open wl_shade.h and under this line:
- Code:
extern uint8_t shadetable[SHADE_COUNT][256];
- Code:
#ifdef USE_ADVSHADES
extern double lightflash;
#endif
- Code:
int GetShade(int scale);
- Code:
int GetShade(int scale
#ifdef USE_ADVSHADES
,int dx=0, int dy=0,int tx1=0, int ty1=0, int tx2=0,int ty2=0, byte sx=64, byte sy=64
#endif
);
Next up is wl_shade.cpp. In that file under "int LSHADE_flag;" add these lines:
- Code:
#ifdef USE_ADVSHADES
double lightflash = 0;
#endif
- Code:
#ifdef USE_ADVSHADES
void InitLevelShadeMap(void);
#endif
- Code:
#ifdef USE_ADVSHADES
//Fill the lightmap:
InitLevelShadeMap();
#endif
- Code:
#ifdef USE_ADVSHADES
double inline GetLightFrag(int x, int y, int tx, int ty, byte sx, byte sy);
double inline FlashlightIntensity(int scale, double radius);
int GetShade(int scale,int dx,int dy,int tx1, int ty1,int tx2, int ty2, byte sx, byte sy)
{ int16_t shade;
//Count light fraction...
double pixradius = (dx*dx + dy*dy*1.4)/viewwidth;
double lightfrag = GetLightFrag(tx1,ty1,tx2,ty2,sx,sy)/256;
//...and limit it:
if(lightfrag > 1) lightfrag = 1;
if(lightfrag < 0) lightfrag = 0;
if(gamestate.flashlight && pixradius < 12)
shade = (int)(SHADE_COUNT*(FlashlightIntensity(scale, pixradius)+lightfrag+lightflash));
else
shade = (int)(SHADE_COUNT*(lightfrag+lightflash));
#else
int GetShade(int scale)
{
int shade = (scale >> 1) / (((viewwidth * 3) >> + 1 + LSHADE_flag); // TODO: reconsider this...
#endif
if(shade > SHADE_COUNT) shade = SHADE_COUNT;
else if(shade < 1) shade = 1;
shade = SHADE_COUNT - shade;
return shade;
}
- Code:
//
//Get light fraction, based on the_fish's code:
#ifdef USE_ADVSHADES
double inline GetLightFrag(int x, int y, int tx, int ty, byte sx, byte sy){
double tx1, ty1, tx2, ty2;
if (tx > x || ty > y){
tx1 = 0.5-((double)sx/TEXTURESIZE);
ty1 = ((double)sy/TEXTURESIZE)-0.5;
}else{
tx1 = ((double)sx/TEXTURESIZE*)-0.5;
ty1 = 0.5-((double)sy/TEXTURESIZE);
}
tx2 = 1-fabs(tx1);
ty2 = 1-fabs(ty1);
if(tx1 > 0){
if(ty1 > 0)
return ((lightMap[x][y] * (tx2*ty2)) + (lightMap[x+1][y] * (tx1*ty2)) +
(lightMap[x][y+1] * (tx2*ty1)) + (lightMap[x+1][y+1] * (tx1*ty1)));
else{
ty1 *= -1;
return ((lightMap[x][y] * (tx2*ty2)) + (lightMap[x+1][y] * (tx1*ty2)) +
(lightMap[x][y-1] * (tx2*ty1)) + (lightMap[x+1][y-1] * (tx1*ty1)));
}
}else{
tx1 *= -1;
if(ty1 > 0)
return ((lightMap[x][y] * (tx2*ty2)) + (lightMap[x-1][y] * (tx1*ty2)) +
(lightMap[x][y+1] * (tx2*ty1)) + (lightMap[x-1][y+1] * (tx1*ty1)));
else{
ty1 *= -1;
return ((lightMap[x][y] * (tx2*ty2)) + (lightMap[x-1][y] * (tx1*ty2)) +
(lightMap[x][y-1] * (tx2*ty1)) + (lightMap[x-1][y-1] * (tx1*ty1)));
}
} return 0;
}
//
//Get the intensity of flashlight, based on the_fish's code:
double inline FlashlightIntensity(int scale, double radius){
return (scale*scale) * (1 - (radius/12)*(radius/12)) / (1000);
}
//
//Fill the lightmap from either objects or 4th-plane:
void InitLevelShadeMap(){
for(int x=0;x<MAPSIZE;x++)
{ for(int y=0;y<MAPSIZE;y++)
{
#ifdef USE_4THPLANE
lightMap[x][y] = MAPSPOT(x,y,3);
#else
switch(MAPSPOT(x,y,1))
{
case 26: //Floor lamp
case 27: //Chandelier
case 37: //Green lamp
#ifdef WOLF
case 68: //Stove
#else
#ifdef SPEAR
case 63: //Red lamp
case 74: //Spear of Destiny
#endif
#endif
//Light sources cast light:
lightMap[x-1][y]=215; lightMap[x+1][y]=215;
lightMap[x][y-1]=215; lightMap[x][y+1]=215;
lightMap[x][y]=255;
break;
}
//Generic shadevalues for the level
//if(lightMap[x][y] == 0) lightMap[x][y] = 150;
#endif
}
}
}
#endif
It is time to change the wl_draw.cpp, so open the file
and just below "GLOBAL VARIABLES" add these lines:
- Code:
#define MAXVISABLE 250
typedef struct
{
short viewx,
viewheight,
shapenum;
#ifdef USE_ADVSHADES
byte x,y; // Get the current tile of object
#endif
short flags; // this must be changed to uint32_t, when you
// you need more than 16-flags for drawing
#ifdef USE_DIR3DSPR
statobj_t *transsprite;
objtype *transactor;
#endif
} visobj_t;
visobj_t vislist[MAXVISABLE];
visobj_t *visptr,*visstep,*farthest;
you just added (should be just above the DrawScaleds-function)...
Return back to the global variables and add these lines just above "3 - D Definitions":
- Code:
int texture;
//Shading variables for the_fish's advanced shading
#ifdef USE_ADVSHADES
int tmpX,tmpY,faceX,faceY;
byte sdwX, sdwY;
bool isHoriz;
void inline GetTileCoords();
bool inline GetLight(int shapenum, uint32_t flags);
#endif
(should be 4 - 6 instances not including the line you just added)...
When that is done, add these lines to the very end of the file:
- Code:
/*
========================
=
= GetTileCoords()
=
= Set the face/tmp X/Y values
= Basef on the_fish's routine
=
========================
*/
#ifdef USE_ADVSHADES
void inline GetTileCoords(){
if (!isHoriz)
{
faceY = tmpY;
if (player->x >> (TILESHIFT-1) > (tmpX*2))
faceX = tmpX+1;
else
faceX = tmpX-1;
}
else
{
faceX = tmpX;
if (player->y >> (TILESHIFT-1) > (tmpY*2))
faceY = tmpY+1;
else
faceY = tmpY-1;
}
}
/*
========================
=
= GetLight()
=
= Check whether to lit the object
=
========================
*/
bool inline GetLight(int shapenum, uint32_t flags){
if(flags & FL_FULLBRIGHT) return true;
switch (shapenum){
//Add here sprites you want to light but you can't set
//with FL_FULLBRIGHT-flag (e.g. animation frames):
case 0:
case 1:
return true;
break;
} return false;
}
#endif
Go back up till you find the ScalePost - function and in that function
change these lines:
- Code:
#ifdef USE_SHADING
byte *curshades = shadetable[GetShade(wallheight[postx])];
#endif
- Code:
#ifdef USE_SHADING
#ifdef USE_ADVSHADES
int vHeight = 0, vWidth = 0;
#endif
byte *curshades = shadetable[GetShade(wallheight[postx])];
#endif
- Code:
#ifdef USE_SHADING
col = curshades[postsource[yw]];
- Code:
#ifdef USE_SHADING
#ifdef USE_ADVSHADES
vWidth = pixx-(viewwidth/2);
vHeight = (yendoffs/vbufPitch)-(viewheight/2);
if(!isHoriz){
sdwX = TEXTURESIZE/2;
sdwY = texture>>TEXTURESHIFT;
}else{
sdwX = texture>>TEXTURESHIFT;
sdwY = TEXTURESIZE/2;
} curshades = shadetable[GetShade(yd,vWidth,vHeight,faceX,faceY,tmpX,tmpY,sdwX,sdwY)];
#endif
col = curshades[postsource[yw]];
- Code:
#ifdef USE_SHADING
col = curshades[postsource[yw]];
- Code:
#ifdef USE_SHADING
#ifdef USE_ADVSHADES
if(gamestate.flashlight){
vHeight = (yendoffs/vbufPitch) - (viewheight/2);
curshades = shadetable[GetShade(yd,vWidth,vHeight,faceX,faceY,tmpX,tmpY,sdwX,sdwY)];
}
#endif
col = curshades[postsource[yw]];
- Code:
#ifdef USE_ADVSHADES
isHoriz = false; GetTileCoords(); //Set horizontal flag
#endif
- Code:
texture = ((yintercept+texdelta)>>TEXTUREFROMFIXEDSHIFT)&TEXTUREMASK;
if (xtilestep == -1)
{
texture = TEXTUREMASK-texture;
xintercept += TILEGLOBAL;
}
- Code:
#ifdef USE_ADVSHADES
isHoriz = true; GetTileCoords(); //Set horizontal flag
#endif
- Code:
#ifdef USE_ADVSHADES
isHoriz = true; GetTileCoords(); //Set horizontal flag
#endif
- Code:
#ifdef USE_ADVSHADES
isHoriz = false; GetTileCoords(); //Set horizontal flag
#endif
add these lines under "int wallpic" (isHoriz must be TRUE for HitHorizPWall):
- Code:
#ifdef USE_ADVSHADES
isHoriz = false; GetTileCoords(); //Set horizontal flag
#endif
- Code:
#ifdef USE_SHADING
byte *curshades;
if(flags & FL_FULLBRIGHT)
curshades = shadetable[0];
else
curshades = shadetable[GetShade(height)];
#endif
- Code:
#ifdef USE_SHADING
byte *curshades;
#ifdef USE_ADVSHADES
bool isLight = GetLight(shapenum,flags);
#else
if(flags & FL_FULLBRIGHT)
curshades = shadetable[0];
else
curshades = shadetable[GetShade(height)];
#endif
#endif
- Code:
#ifdef USE_SHADING
col=curshades[((byte *)shape)[newstart+j]];
- Code:
#ifdef USE_SHADING
#ifdef USE_ADVSHADES
if(isLight){
curshades = shadetable[0];
}else{
curshades = shadetable[GetShade(scale,rpix-viewwidth/2,scrstarty-(viewheight/2),
farthest->x,farthest->y,tmpX,tmpY,sdwX,sdwY)];
}
#endif
col=curshades[((byte *)shape)[newstart+j]];
- Code:
col=((byte *)shape)[newstart+j];
- Code:
#ifdef USE_ADVSHADES
byte *curshades = shadetable[GetShade(scale,xcenter+lpix-(viewwidth),
scrstarty-(viewheight/2),player->tilex,player->tiley,tmpX,tmpY,sdwX,sdwY)];
col = curshades[((byte *)shape)[newstart+j]];
#else
col=((byte *)shape)[newstart+j];
#endif
- Code:
#ifdef USE_DIR3DSPR
if(statptr->flags & FL_DIR_MASK)
visptr->transsprite=statptr;
else
visptr->transsprite=NULL;
#endif
Under that block add this one:
- Code:
#ifdef USE_ADVSHADES
//Encode the tile coordinates:
visptr->x = statptr->tilex;
visptr->y = statptr->tiley;
#endif
Go few lines down until you see:
- Code:
//
// could be in any of the nine surrounding tiles
//
- Code:
#ifdef USE_ADVSHADES
//Encode the tile coordinates:
visptr->x = statptr->tilex;
visptr->y = statptr->tiley;
#endif
- Code:
if (obj->state->rotate)
visptr->shapenum += CalcRotate (obj);
- Code:
#ifdef USE_ADVSHADES
//WSJs glowing enemies:
if (obj->state->fullbright == true)
obj->flags |= FL_FULLBRIGHT; // actor is "lit up"
else if(obj->flags & FL_FULLBRIGHT)
obj->flags &= ~FL_FULLBRIGHT; // back to normal lighting
#endif
- Code:
#ifdef USE_DIR3DSPR
if(farthest->transsprite)
Scale3DShape(vbuf, vbufPitch, farthest->transsprite);
And change them to this:
- Code:
#ifdef USE_DIR3DSPR
if(farthest->transsprite)
#ifdef USE_ADVSHADES
Scale3DShape(vbuf, vbufPitch, farthest->transsprite, tmpX, tmpY, farthest->x, farthest->y);
#else
Scale3DShape(vbuf, vbufPitch, farthest->transsprite);
#endif
- Code:
SimpleScaleShape(viewwidth/2,shapenum,viewheight+1);
- Code:
#ifdef USE_ADVSHADES
//Light area when shooting
if(shapenum == weaponscale[gamestate.weapon]+3 && gamestate.weapon != wp_knife)
lightflash = 1;
else
lightflash = 0;
if(lightflash>0){
lightflash*=2; //Adjust for intensity
SimpleScaleShape(viewwidth/2,shapenum,viewheight+1);
lightflash/=2; //Must match the line above
} else
#endif
Search for "vertentry:" and when you have found it go down until you see these lines:
- Code:
if(xspot>=maparea) break;
tilehit=((uint16_t *)tilemap)[xspot];
- Code:
#ifdef USE_ADVSHADES
//Get tile coordinates
tmpX = xspot>>6;
tmpY = xspot & 0x3F;
#endif
- Code:
if(yspot>=maparea) break;
tilehit=((byte *)tilemap)[yspot];
- Code:
//Get tile coordinates:
tmpX = yspot>>6;
tmpY = yspot & 0x3F;
After that is done, go to the WallRefresh - function and add these
lines just before the call for ScalePost:
- Code:
#ifdef USE_ADVSHADES
GetTileCoords();
#endif
- Code:
#ifdef USE_ADVSHADES
sdwX = 64; sdwY = 64; //Reset shadow
#endif
And thats it for the wl_draw.cpp!!!
Open the wl_dir3dspr.cpp and change the beginning of Scale3DShaper - function from this:
- Code:
void Scale3DShaper(int x1, int x2, int shapenum, uint32_t flags, fixed ny1, fixed ny2,
fixed nx1, fixed nx2, byte *vbuf, unsigned vbufPitch)
- Code:
void Scale3DShaper(int x1, int x2, int shapenum, uint32_t flags, fixed ny1, fixed ny2,
fixed nx1, fixed nx2, byte *vbuf, unsigned vbufPitch
#ifdef USE_ADVSHADES
,int tx, int ty, int fx, int fy
#endif
)
- Code:
#ifdef USE_SHADING
byte *curshades;
if(flags & FL_FULLBRIGHT)
curshades = shadetable[0];
else
curshades = shadetable[GetShade(scale1<<3)];
#endif
- Code:
#ifdef USE_SHADING
byte *curshades;
#ifdef USE_ADVSHADES
bool isLight = (flags & FL_FULLBRIGHT)? true : false;
#else
if(flags & FL_FULLBRIGHT)
curshades = shadetable[0];
else
curshades = shadetable[GetShade(scale1<<3)];
#endif
#endif
- Code:
#ifdef USE_SHADING
col=curshades[((byte *)shape)[newstart+j]];
- Code:
#ifdef USE_SHADING
#ifdef USE_ADVSHADES
if(isLight)
curshades = shadetable[0];
else
curshades = shadetable[GetShade(scale1,xpos[i]-(viewwidth/2),
scrstarty-(viewheight/2),tx,ty,fx,fy)];
#endif
col=curshades[((byte *)shape)[newstart+j]];
- Code:
void Scale3DShape(byte *vbuf, unsigned vbufPitch, statobj_t *ob)
- Code:
void Scale3DShape(byte *vbuf, unsigned vbufPitch, statobj_t *ob
#ifdef USE_ADVSHADES
,int tx, int ty, int fx, int fy
#endif
)
- Code:
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);
}
- Code:
if(viewx2 < viewx1)
{
Scale3DShaper(viewx2,viewx1,ob->shapenum,ob->flags,ny2,ny1,nx2,nx1,vbuf,vbufPitch
#ifdef USE_ADVSHADES
,tx,ty,fx,fy
#endif
);
}
else
{
Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch
#ifdef USE_ADVSHADES
,tx,ty,fx,fy
#endif
);
}
It is time to open the last file we need to edit: wl_floorceiling.cpp!
In DrawFloorAndCeiling - function search for these lines
- Code:
#ifdef USE_SHADING
byte *curshades = shadetable[GetShade(y << 3)];
#endif
- Code:
#ifdef USE_SHADING
#ifndef USE_ADVSHADES
byte *curshades = shadetable[GetShade(y << 3)];
#endif
#endif
- Code:
unsigned texoffs = (u << TEXTURESHIFT) + (TEXTURESIZE - 1) - v;
#ifdef USE_SHADING
- Code:
unsigned texoffs = (u << TEXTURESHIFT) + (TEXTURESIZE - 1) - v;
// Needed for AlumiuNs transperent ceiling fix
byte color1=*(toptex+texoffs);
byte color2=*(bottex+texoffs);
#ifdef USE_SHADING
#ifdef USE_ADVSHADES
unsigned short shade = GetShade(y,x-(viewwidth/2),y,curx,cury,curx,cury,u,v);
if(curtoptex && color1 != 0xff)
vbuf[top_add] = shadetable[shade][color1];
if(curbottex && color2 != 0xff)
vbuf[bot_add] = shadetable[shade][color2];
#else
if(curtoptex && color1 != 0xff)
vbuf[top_add] = curshades[toptex[texoffs]];
if(curbottex && color2 != 0xff)
vbuf[bot_add] = curshades[bottex[texoffs]];
#endif
#else
if(curtoptex && color1 != 0xff)
vbuf[top_add] = toptex[texoffs];
if(curbottex && color2 != 0xff)
vbuf[bot_add] = bottex[texoffs];
#endif
If you want the flashlight to be a pickable object, do the following changes...
Search for bo_alpo in the files (search should return
In wl_def.h search for "bo_alpo" and add this line under it:
- Code:
bo_flashlight,
- Code:
bool flashlight;
- Code:
bool gotlight;
found, add this line under them:
- Code:
gamestate.gotlight = false; //Player has no flashlight
Then search for "flashlight" in wl_play.cpp and replace this line
- Code:
if(Keyboard[sc_Z])
- Code:
if(Keyboard[sc_Z] && gamestate.gotlight)
- Code:
case bo_flashlight:
After the bo_alpo - case add the following block:
- Code:
case bo_flashlight:
if(gamestate.gotlight) return; //Player already has light
SD_PlaySound (BONUS1SND);
gamestate.gotlight = true;
break;
to be your new flashlight item...
Okay... Last thing you want to do is to add the fourth plane to the game because it would
give you more freedom to create lightmaps than trying to generate the lightmap from maps objects...
Here is tutorial from Adam Biser for adding 4th plane (modified it a bit)...
Open wl_ca.h and in the beginning of file replace this block:
- Code:
#ifdef USE_FLOORCEILINGTEX
#define MAPPLANES 3
#else
#define MAPPLANES 2
#endif
- Code:
//You propably will be using textured floors and ceilings anyway...
#ifdef USE_4THPLANE
#define MAPPLANES 4
#else
#ifdef USE_FLOORCEILINGTEX
#define MAPPLANES 3
#else
#define MAPPLANES 2
#endif
#endif
- Code:
typedef struct
{
int32_t planestart[3];
word planelength[3];
Then open wl_ca.cpp and search for mapfiletype - struct...
And change it to this:
- Code:
typedef struct
{ word RLEWtag;
int16_t numplanes;
int32_t headeroffsets[100];
byte tileinfo[];
} mapfiletype;
- Code:
//
// Read fourth plane:
//
#ifdef USE_4THPLANE
map = mapsegs[3];
for (y=0;y<mapheight;y++)
{
for (x=0;x<mapwidth;x++)
{
tile = *map++;
#ifdef USE_ADVSHADES
//Fill the lightmap:
lightMap[x][y] = (int)tile;
#endif
}
}
#endif
After these lines:
- Code:
//
// take out the ambush markers
//
map = mapsegs[0];
for (y=0;y<mapheight;y++)
{
for (x=0;x<mapwidth;x++)
{
tile = *map++;
if (tile == AMBUSHTILE)
{
tilemap[x][y] = 0;
if ( (unsigned)(uintptr_t)actorat[x][y] == AMBUSHTILE)
actorat[x][y] = NULL;
if (*map >= AREATILE)
tile = *map;
if (*(map-1-mapwidth) >= AREATILE)
tile = *(map-1-mapwidth);
if (*(map-1+mapwidth) >= AREATILE)
tile = *(map-1+mapwidth);
if ( *(map-2) >= AREATILE)
tile = *(map-2);
*(map-1) = tile;
}
}
}
IMPORTANT! Creating and editing the 4th plane only works in WDC...
Last edited by WLHack on Fri Aug 29, 2014 8:19 am; edited 8 times in total