2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
//**************************************************************************
|
|
|
|
//**
|
|
|
|
//** TEMPLATE.C
|
|
|
|
//**
|
|
|
|
//**************************************************************************
|
|
|
|
|
|
|
|
// HEADER FILES ------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "p_local.h"
|
|
|
|
#include "m_swap.h"
|
|
|
|
#include "w_wad.h"
|
|
|
|
#include "templates.h"
|
|
|
|
#include "r_sky.h"
|
|
|
|
#include "r_defs.h"
|
2008-05-15 17:16:32 +00:00
|
|
|
#include "p_setup.h"
|
2008-09-14 23:54:38 +00:00
|
|
|
#include "g_level.h"
|
2011-07-06 07:35:36 +00:00
|
|
|
#include "r_data/colormaps.h"
|
2014-07-30 02:39:05 +00:00
|
|
|
#include "gi.h"
|
2016-02-15 08:25:48 +00:00
|
|
|
#include "p_spec.h"
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// MACROS ------------------------------------------------------------------
|
|
|
|
|
2014-08-08 03:27:48 +00:00
|
|
|
//#define SHADE2LIGHT(s) (160-2*(s))
|
|
|
|
#define SHADE2LIGHT(s) (255-2*s)
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// TYPES -------------------------------------------------------------------
|
|
|
|
|
|
|
|
//ceilingstat/floorstat:
|
|
|
|
// bit 0: 1 = parallaxing, 0 = not "P"
|
|
|
|
// bit 1: 1 = groudraw, 0 = not
|
|
|
|
// bit 2: 1 = swap x&y, 0 = not "F"
|
|
|
|
// bit 3: 1 = double smooshiness "E"
|
|
|
|
// bit 4: 1 = x-flip "F"
|
|
|
|
// bit 5: 1 = y-flip "F"
|
|
|
|
// bit 6: 1 = Align texture to first wall of sector "R"
|
|
|
|
// bits 7-8: "T"
|
|
|
|
// 00 = normal floors
|
|
|
|
// 01 = masked floors
|
|
|
|
// 10 = transluscent masked floors
|
|
|
|
// 11 = reverse transluscent masked floors
|
|
|
|
// bits 9-15: reserved
|
|
|
|
|
|
|
|
//40 bytes
|
2009-03-28 11:49:44 +00:00
|
|
|
struct sectortype
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
SWORD wallptr, wallnum;
|
|
|
|
SDWORD ceilingz, floorz;
|
|
|
|
SWORD ceilingstat, floorstat;
|
|
|
|
SWORD ceilingpicnum, ceilingheinum;
|
|
|
|
SBYTE ceilingshade;
|
|
|
|
BYTE ceilingpal, ceilingxpanning, ceilingypanning;
|
|
|
|
SWORD floorpicnum, floorheinum;
|
|
|
|
SBYTE floorshade;
|
|
|
|
BYTE floorpal, floorxpanning, floorypanning;
|
|
|
|
BYTE visibility, filler;
|
|
|
|
SWORD lotag, hitag, extra;
|
2009-03-28 11:49:44 +00:00
|
|
|
};
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
//cstat:
|
|
|
|
// bit 0: 1 = Blocking wall (use with clipmove, getzrange) "B"
|
|
|
|
// bit 1: 1 = bottoms of invisible walls swapped, 0 = not "2"
|
|
|
|
// bit 2: 1 = align picture on bottom (for doors), 0 = top "O"
|
|
|
|
// bit 3: 1 = x-flipped, 0 = normal "F"
|
|
|
|
// bit 4: 1 = masking wall, 0 = not "M"
|
|
|
|
// bit 5: 1 = 1-way wall, 0 = not "1"
|
|
|
|
// bit 6: 1 = Blocking wall (use with hitscan / cliptype 1) "H"
|
|
|
|
// bit 7: 1 = Transluscence, 0 = not "T"
|
|
|
|
// bit 8: 1 = y-flipped, 0 = normal "F"
|
|
|
|
// bit 9: 1 = Transluscence reversing, 0 = normal "T"
|
|
|
|
// bits 10-15: reserved
|
|
|
|
|
|
|
|
//32 bytes
|
2009-03-28 11:49:44 +00:00
|
|
|
struct walltype
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
SDWORD x, y;
|
|
|
|
SWORD point2, nextwall, nextsector, cstat;
|
|
|
|
SWORD picnum, overpicnum;
|
|
|
|
SBYTE shade;
|
|
|
|
BYTE pal, xrepeat, yrepeat, xpanning, ypanning;
|
|
|
|
SWORD lotag, hitag, extra;
|
2009-03-28 11:49:44 +00:00
|
|
|
};
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
//cstat:
|
|
|
|
// bit 0: 1 = Blocking sprite (use with clipmove, getzrange) "B"
|
|
|
|
// bit 1: 1 = transluscence, 0 = normal "T"
|
|
|
|
// bit 2: 1 = x-flipped, 0 = normal "F"
|
|
|
|
// bit 3: 1 = y-flipped, 0 = normal "F"
|
|
|
|
// bits 5-4: 00 = FACE sprite (default) "R"
|
|
|
|
// 01 = WALL sprite (like masked walls)
|
|
|
|
// 10 = FLOOR sprite (parallel to ceilings&floors)
|
|
|
|
// bit 6: 1 = 1-sided sprite, 0 = normal "1"
|
|
|
|
// bit 7: 1 = Real centered centering, 0 = foot center "C"
|
|
|
|
// bit 8: 1 = Blocking sprite (use with hitscan / cliptype 1) "H"
|
|
|
|
// bit 9: 1 = Transluscence reversing, 0 = normal "T"
|
|
|
|
// bits 10-14: reserved
|
|
|
|
// bit 15: 1 = Invisible sprite, 0 = not invisible
|
|
|
|
|
|
|
|
//44 bytes
|
2009-03-28 11:49:44 +00:00
|
|
|
struct spritetype
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
SDWORD x, y, z;
|
|
|
|
SWORD cstat, picnum;
|
|
|
|
SBYTE shade;
|
|
|
|
BYTE pal, clipdist, filler;
|
|
|
|
BYTE xrepeat, yrepeat;
|
|
|
|
SBYTE xoffset, yoffset;
|
|
|
|
SWORD sectnum, statnum;
|
|
|
|
SWORD ang, owner, xvel, yvel, zvel;
|
|
|
|
SWORD lotag, hitag, extra;
|
2009-03-28 11:49:44 +00:00
|
|
|
};
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2010-03-18 05:01:10 +00:00
|
|
|
// I used to have all the Xobjects mapped out. Not anymore.
|
|
|
|
// (Thanks for the great firmware, Seagate!)
|
|
|
|
struct Xsprite
|
|
|
|
{
|
|
|
|
BYTE NotReallyPadding[16];
|
|
|
|
WORD Data1;
|
|
|
|
WORD Data2;
|
|
|
|
WORD Data3;
|
|
|
|
WORD ThisIsntPaddingEither;
|
|
|
|
DWORD NorThis:2;
|
|
|
|
DWORD Data4:16;
|
|
|
|
DWORD WhatIsThisIDontEven:14;
|
|
|
|
BYTE ThisNeedsToBe56Bytes[28];
|
|
|
|
};
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
struct SlopeWork
|
|
|
|
{
|
|
|
|
walltype *wal;
|
|
|
|
walltype *wal2;
|
|
|
|
long dx, dy, i, x[3], y[3], z[3];
|
|
|
|
long heinum;
|
|
|
|
};
|
|
|
|
|
|
|
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
|
|
|
|
|
|
|
void P_AdjustLine (line_t *line);
|
|
|
|
|
|
|
|
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
|
|
|
|
|
|
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
|
|
|
|
2008-05-08 08:06:26 +00:00
|
|
|
static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **sprites, int *numsprites);
|
2006-02-24 04:48:15 +00:00
|
|
|
static void LoadSectors (sectortype *bsectors);
|
|
|
|
static void LoadWalls (walltype *walls, int numwalls, sectortype *bsectors);
|
2010-03-18 05:01:10 +00:00
|
|
|
static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, sectortype *bsectors, FMapThing *mapthings);
|
2006-02-24 04:48:15 +00:00
|
|
|
static vertex_t *FindVertex (fixed_t x, fixed_t y);
|
2008-05-08 08:06:26 +00:00
|
|
|
static void CreateStartSpot (fixed_t *pos, FMapThing *start);
|
2006-02-24 04:48:15 +00:00
|
|
|
static void CalcPlane (SlopeWork &slope, secplane_t &plane);
|
|
|
|
static void Decrypt (void *to, const void *from, int len, int key);
|
|
|
|
|
|
|
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
|
|
|
|
|
|
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
|
|
|
|
|
|
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
|
|
|
|
|
|
|
// CODE --------------------------------------------------------------------
|
|
|
|
|
2008-05-15 17:16:32 +00:00
|
|
|
bool P_IsBuildMap(MapData *map)
|
|
|
|
{
|
|
|
|
DWORD len = map->Size(ML_LABEL);
|
2010-03-18 01:07:50 +00:00
|
|
|
if (len < 4)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2008-05-15 17:16:32 +00:00
|
|
|
BYTE *data = new BYTE[len];
|
|
|
|
|
|
|
|
map->Seek(ML_LABEL);
|
|
|
|
map->Read(ML_LABEL, data);
|
|
|
|
|
|
|
|
// Check for a Blood map.
|
|
|
|
if (*(DWORD *)data == MAKE_ID('B','L','M','\x1a'))
|
|
|
|
{
|
|
|
|
delete[] data;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-02-07 20:17:50 +00:00
|
|
|
const int numsec = LittleShort(*(WORD *)(data + 20));
|
2008-05-15 17:16:32 +00:00
|
|
|
int numwalls;
|
|
|
|
|
2013-02-07 20:17:50 +00:00
|
|
|
if (len < 26 + numsec*sizeof(sectortype) ||
|
|
|
|
(numwalls = LittleShort(*(WORD *)(data + 22 + numsec*sizeof(sectortype))),
|
|
|
|
len < 24 + numsec*sizeof(sectortype) + numwalls*sizeof(walltype)) ||
|
2008-05-15 17:16:32 +00:00
|
|
|
LittleLong(*(DWORD *)data) != 7 ||
|
|
|
|
LittleShort(*(WORD *)(data + 16)) >= 2048)
|
|
|
|
{ // Can't possibly be a version 7 BUILD map
|
|
|
|
delete[] data;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
delete[] data;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// P_LoadBuildMap
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
2008-05-08 08:06:26 +00:00
|
|
|
bool P_LoadBuildMap (BYTE *data, size_t len, FMapThing **sprites, int *numspr)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
if (len < 26)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check for a Blood map.
|
|
|
|
if (*(DWORD *)data == MAKE_ID('B','L','M','\x1a'))
|
|
|
|
{
|
|
|
|
return P_LoadBloodMap (data, len, sprites, numspr);
|
|
|
|
}
|
|
|
|
|
2013-02-07 20:17:50 +00:00
|
|
|
const int numsec = LittleShort(*(WORD *)(data + 20));
|
2006-02-24 04:48:15 +00:00
|
|
|
int numwalls;
|
|
|
|
int numsprites;
|
|
|
|
|
2013-02-07 20:17:50 +00:00
|
|
|
if (len < 26 + numsec*sizeof(sectortype) ||
|
|
|
|
(numwalls = LittleShort(*(WORD *)(data + 22 + numsec*sizeof(sectortype))),
|
|
|
|
len < 24 + numsec*sizeof(sectortype) + numwalls*sizeof(walltype)) ||
|
2006-02-24 04:48:15 +00:00
|
|
|
LittleLong(*(DWORD *)data) != 7 ||
|
|
|
|
LittleShort(*(WORD *)(data + 16)) >= 2048)
|
|
|
|
{ // Can't possibly be a version 7 BUILD map
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-02-07 20:17:50 +00:00
|
|
|
numsectors = numsec;
|
2006-02-24 04:48:15 +00:00
|
|
|
LoadSectors ((sectortype *)(data + 22));
|
|
|
|
LoadWalls ((walltype *)(data + 24 + numsectors*sizeof(sectortype)), numwalls,
|
|
|
|
(sectortype *)(data + 22));
|
|
|
|
|
|
|
|
numsprites = *(WORD *)(data + 24 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype));
|
2008-05-08 08:06:26 +00:00
|
|
|
*sprites = new FMapThing[numsprites + 1];
|
2006-02-24 04:48:15 +00:00
|
|
|
CreateStartSpot ((fixed_t *)(data + 4), *sprites);
|
|
|
|
*numspr = 1 + LoadSprites ((spritetype *)(data + 26 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype)),
|
2010-03-18 05:01:10 +00:00
|
|
|
NULL, numsprites, (sectortype *)(data + 22), *sprites + 1);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// P_LoadBloodMap
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
2008-05-08 08:06:26 +00:00
|
|
|
static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int *numspr)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
BYTE infoBlock[37];
|
|
|
|
int mapver = data[5];
|
|
|
|
DWORD matt;
|
2014-08-08 03:00:02 +00:00
|
|
|
int numRevisions, numWalls, numsprites, skyLen, visibility, parallaxType;
|
2006-02-24 04:48:15 +00:00
|
|
|
int i;
|
|
|
|
int k;
|
|
|
|
|
|
|
|
if (mapver != 6 && mapver != 7)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
matt = *(DWORD *)(data + 28);
|
|
|
|
if (matt != 0 &&
|
|
|
|
matt != MAKE_ID('M','a','t','t') &&
|
|
|
|
matt != MAKE_ID('t','t','a','M'))
|
|
|
|
{
|
|
|
|
Decrypt (infoBlock, data + 6, 37, 0x7474614d);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy (infoBlock, data + 6, 37);
|
|
|
|
}
|
2014-08-08 03:00:02 +00:00
|
|
|
skyLen = 2 << LittleShort(*(WORD *)(infoBlock + 16));
|
|
|
|
visibility = LittleLong(*(DWORD *)(infoBlock + 18));
|
|
|
|
parallaxType = infoBlock[26];
|
2010-03-18 02:09:08 +00:00
|
|
|
numRevisions = LittleLong(*(DWORD *)(infoBlock + 27));
|
|
|
|
numsectors = LittleShort(*(WORD *)(infoBlock + 31));
|
|
|
|
numWalls = LittleShort(*(WORD *)(infoBlock + 33));
|
|
|
|
numsprites = LittleShort(*(WORD *)(infoBlock + 35));
|
2014-08-08 03:00:02 +00:00
|
|
|
Printf("Visibility: %d\n", visibility);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
if (mapver == 7)
|
|
|
|
{
|
|
|
|
// Version 7 has some extra stuff after the info block. This
|
|
|
|
// includes a copyright, and I have no idea what the rest of
|
|
|
|
// it is.
|
|
|
|
data += 171;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
data += 43;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Skip the sky info.
|
|
|
|
data += skyLen;
|
|
|
|
|
|
|
|
sectortype *bsec = new sectortype[numsectors];
|
|
|
|
walltype *bwal = new walltype[numWalls];
|
|
|
|
spritetype *bspr = new spritetype[numsprites];
|
2010-03-18 05:01:10 +00:00
|
|
|
Xsprite *xspr = new Xsprite[numsprites];
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// Read sectors
|
|
|
|
k = numRevisions * sizeof(sectortype);
|
|
|
|
for (i = 0; i < numsectors; ++i)
|
|
|
|
{
|
|
|
|
if (mapver == 7)
|
|
|
|
{
|
|
|
|
Decrypt (&bsec[i], data, sizeof(sectortype), k);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy (&bsec[i], data, sizeof(sectortype));
|
|
|
|
}
|
|
|
|
data += sizeof(sectortype);
|
|
|
|
if (bsec[i].extra > 0) // skip Xsector
|
|
|
|
{
|
|
|
|
data += 60;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read walls
|
|
|
|
k |= 0x7474614d;
|
|
|
|
for (i = 0; i < numWalls; ++i)
|
|
|
|
{
|
|
|
|
if (mapver == 7)
|
|
|
|
{
|
|
|
|
Decrypt (&bwal[i], data, sizeof(walltype), k);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy (&bwal[i], data, sizeof(walltype));
|
|
|
|
}
|
|
|
|
data += sizeof(walltype);
|
|
|
|
if (bwal[i].extra > 0) // skip Xwall
|
|
|
|
{
|
|
|
|
data += 24;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read sprites
|
|
|
|
k = (numRevisions * sizeof(spritetype)) | 0x7474614d;
|
|
|
|
for (i = 0; i < numsprites; ++i)
|
|
|
|
{
|
|
|
|
if (mapver == 7)
|
|
|
|
{
|
|
|
|
Decrypt (&bspr[i], data, sizeof(spritetype), k);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy (&bspr[i], data, sizeof(spritetype));
|
|
|
|
}
|
|
|
|
data += sizeof(spritetype);
|
2010-03-18 05:01:10 +00:00
|
|
|
if (bspr[i].extra > 0) // copy Xsprite
|
|
|
|
{
|
2010-03-29 20:25:08 +00:00
|
|
|
assert(sizeof(Xsprite) == 56);
|
2010-03-18 05:01:10 +00:00
|
|
|
memcpy(&xspr[i], data, sizeof(Xsprite));
|
|
|
|
data += sizeof(Xsprite);
|
|
|
|
}
|
|
|
|
else
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2010-03-18 05:01:10 +00:00
|
|
|
memset(&xspr[i], 0, sizeof(Xsprite));
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now convert to Doom format, since we've extracted all the standard
|
|
|
|
// BUILD info from the map we need. (Sprites are ignored.)
|
|
|
|
LoadSectors (bsec);
|
|
|
|
LoadWalls (bwal, numWalls, bsec);
|
2014-07-30 02:39:05 +00:00
|
|
|
*mapthings = new FMapThing[numsprites];
|
|
|
|
*numspr = LoadSprites (bspr, xspr, numsprites, bsec, *mapthings);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
delete[] bsec;
|
|
|
|
delete[] bwal;
|
|
|
|
delete[] bspr;
|
2010-03-18 05:01:10 +00:00
|
|
|
delete[] xspr;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// LoadSectors
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
static void LoadSectors (sectortype *bsec)
|
|
|
|
{
|
|
|
|
FDynamicColormap *map = GetSpecialLights (PalEntry (255,255,255), level.fadeto, 0);
|
|
|
|
sector_t *sec;
|
|
|
|
char tnam[9];
|
|
|
|
|
|
|
|
sec = sectors = new sector_t[numsectors];
|
|
|
|
memset (sectors, 0, sizeof(sector_t)*numsectors);
|
|
|
|
|
2010-03-18 02:09:08 +00:00
|
|
|
sectors[0].e = new extsector_t[numsectors];
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
for (int i = 0; i < numsectors; ++i, ++bsec, ++sec)
|
|
|
|
{
|
|
|
|
bsec->wallptr = WORD(bsec->wallptr);
|
|
|
|
bsec->wallnum = WORD(bsec->wallnum);
|
|
|
|
bsec->ceilingstat = WORD(bsec->ceilingstat);
|
|
|
|
bsec->floorstat = WORD(bsec->floorstat);
|
|
|
|
|
2010-03-18 02:09:08 +00:00
|
|
|
sec->e = §ors[0].e[i];
|
2008-08-16 20:19:35 +00:00
|
|
|
sec->SetPlaneTexZ(sector_t::floor, -(LittleLong(bsec->floorz) << 8));
|
|
|
|
sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor);
|
2006-02-24 04:48:15 +00:00
|
|
|
sec->floorplane.c = FRACUNIT;
|
|
|
|
sec->floorplane.ic = FRACUNIT;
|
About a week's worth of changes here. As a heads-up, I wouldn't be
surprised if this doesn't build in Linux right now. The CMakeLists.txt
were checked with MinGW and NMake, but how they fair under Linux is an
unknown to me at this time.
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
- Added the gdtoa package from netlib's fp library so that ZDoom's printf-style
formatting can be entirely independant of the CRT.
SVN r1082 (trunk)
2008-07-23 04:57:26 +00:00
|
|
|
mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(bsec->floorpicnum));
|
2008-08-16 20:19:35 +00:00
|
|
|
sec->SetTexture(sector_t::floor, TexMan.GetTexture (tnam, FTexture::TEX_Build));
|
2008-06-14 15:26:16 +00:00
|
|
|
sec->SetXScale(sector_t::floor, (bsec->floorstat & 8) ? FRACUNIT*2 : FRACUNIT);
|
|
|
|
sec->SetYScale(sector_t::floor, (bsec->floorstat & 8) ? FRACUNIT*2 : FRACUNIT);
|
|
|
|
sec->SetXOffset(sector_t::floor, (bsec->floorxpanning << FRACBITS) + (32 << FRACBITS));
|
|
|
|
sec->SetYOffset(sector_t::floor, bsec->floorypanning << FRACBITS);
|
2008-08-16 20:19:35 +00:00
|
|
|
sec->SetPlaneLight(sector_t::floor, SHADE2LIGHT (bsec->floorshade));
|
2009-09-17 10:40:38 +00:00
|
|
|
sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2008-08-16 20:19:35 +00:00
|
|
|
sec->SetPlaneTexZ(sector_t::ceiling, -(LittleLong(bsec->ceilingz) << 8));
|
|
|
|
sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling);
|
2006-02-24 04:48:15 +00:00
|
|
|
sec->ceilingplane.c = -FRACUNIT;
|
|
|
|
sec->ceilingplane.ic = -FRACUNIT;
|
About a week's worth of changes here. As a heads-up, I wouldn't be
surprised if this doesn't build in Linux right now. The CMakeLists.txt
were checked with MinGW and NMake, but how they fair under Linux is an
unknown to me at this time.
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
- Added the gdtoa package from netlib's fp library so that ZDoom's printf-style
formatting can be entirely independant of the CRT.
SVN r1082 (trunk)
2008-07-23 04:57:26 +00:00
|
|
|
mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(bsec->ceilingpicnum));
|
2008-08-16 20:19:35 +00:00
|
|
|
sec->SetTexture(sector_t::ceiling, TexMan.GetTexture (tnam, FTexture::TEX_Build));
|
2006-02-24 04:48:15 +00:00
|
|
|
if (bsec->ceilingstat & 1)
|
|
|
|
{
|
2008-08-16 20:19:35 +00:00
|
|
|
sky1texture = sky2texture = sec->GetTexture(sector_t::ceiling);
|
|
|
|
sec->SetTexture(sector_t::ceiling, skyflatnum);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
2008-06-14 15:26:16 +00:00
|
|
|
sec->SetXScale(sector_t::ceiling, (bsec->ceilingstat & 8) ? FRACUNIT*2 : FRACUNIT);
|
|
|
|
sec->SetYScale(sector_t::ceiling, (bsec->ceilingstat & 8) ? FRACUNIT*2 : FRACUNIT);
|
|
|
|
sec->SetXOffset(sector_t::ceiling, (bsec->ceilingxpanning << FRACBITS) + (32 << FRACBITS));
|
|
|
|
sec->SetYOffset(sector_t::ceiling, bsec->ceilingypanning << FRACBITS);
|
2008-08-16 20:19:35 +00:00
|
|
|
sec->SetPlaneLight(sector_t::ceiling, SHADE2LIGHT (bsec->ceilingshade));
|
2009-09-17 10:40:38 +00:00
|
|
|
sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2008-08-16 20:19:35 +00:00
|
|
|
sec->lightlevel = (sec->GetPlaneLight(sector_t::floor) + sec->GetPlaneLight(sector_t::ceiling)) / 2;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
sec->seqType = -1;
|
2010-08-07 04:32:18 +00:00
|
|
|
sec->SeqName = NAME_None;
|
2006-02-24 04:48:15 +00:00
|
|
|
sec->nextsec = -1;
|
|
|
|
sec->prevsec = -1;
|
|
|
|
sec->gravity = 1.f;
|
|
|
|
sec->friction = ORIG_FRICTION;
|
|
|
|
sec->movefactor = ORIG_FRICTION_FACTOR;
|
|
|
|
sec->ColorMap = map;
|
|
|
|
sec->ZoneNumber = 0xFFFF;
|
2016-01-09 11:10:36 +00:00
|
|
|
sec->terrainnum[sector_t::ceiling] = sec->terrainnum[sector_t::floor] = -1;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
if (bsec->floorstat & 4)
|
|
|
|
{
|
2008-06-14 15:26:16 +00:00
|
|
|
sec->SetAngle(sector_t::floor, ANGLE_90);
|
|
|
|
sec->SetXScale(sector_t::floor, -sec->GetXScale(sector_t::floor));
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
if (bsec->floorstat & 16)
|
|
|
|
{
|
2008-06-14 15:26:16 +00:00
|
|
|
sec->SetXScale(sector_t::floor, -sec->GetXScale(sector_t::floor));
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
if (bsec->floorstat & 32)
|
|
|
|
{
|
2008-06-14 15:26:16 +00:00
|
|
|
sec->SetYScale(sector_t::floor, -sec->GetYScale(sector_t::floor));
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bsec->ceilingstat & 4)
|
|
|
|
{
|
2008-06-14 15:26:16 +00:00
|
|
|
sec->SetAngle(sector_t::ceiling, ANGLE_90);
|
|
|
|
sec->SetYScale(sector_t::ceiling, -sec->GetYScale(sector_t::ceiling));
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
if (bsec->ceilingstat & 16)
|
|
|
|
{
|
2008-06-14 15:26:16 +00:00
|
|
|
sec->SetXScale(sector_t::ceiling, -sec->GetXScale(sector_t::ceiling));
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
if (bsec->ceilingstat & 32)
|
|
|
|
{
|
2008-06-14 15:26:16 +00:00
|
|
|
sec->SetYScale(sector_t::ceiling, -sec->GetYScale(sector_t::ceiling));
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// LoadWalls
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
// Setting numvertexes to the same as numwalls is overly conservative,
|
|
|
|
// but the extra vertices will be removed during the BSP building pass.
|
|
|
|
numsides = numvertexes = numwalls;
|
|
|
|
numlines = 0;
|
|
|
|
|
|
|
|
sides = new side_t[numsides];
|
|
|
|
memset (sides, 0, numsides*sizeof(side_t));
|
|
|
|
|
|
|
|
vertexes = new vertex_t[numvertexes];
|
|
|
|
numvertexes = 0;
|
|
|
|
|
|
|
|
// First mark each sidedef with the sector it belongs to
|
|
|
|
for (i = 0; i < numsectors; ++i)
|
|
|
|
{
|
|
|
|
if (bsec[i].wallptr >= 0)
|
|
|
|
{
|
|
|
|
for (j = 0; j < bsec[i].wallnum; ++j)
|
|
|
|
{
|
|
|
|
sides[j + bsec[i].wallptr].sector = sectors + i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now copy wall properties to their matching sidedefs
|
|
|
|
for (i = 0; i < numwalls; ++i)
|
|
|
|
{
|
|
|
|
char tnam[9];
|
2008-06-15 18:36:26 +00:00
|
|
|
FTextureID overpic, pic;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
About a week's worth of changes here. As a heads-up, I wouldn't be
surprised if this doesn't build in Linux right now. The CMakeLists.txt
were checked with MinGW and NMake, but how they fair under Linux is an
unknown to me at this time.
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
- Added the gdtoa package from netlib's fp library so that ZDoom's printf-style
formatting can be entirely independant of the CRT.
SVN r1082 (trunk)
2008-07-23 04:57:26 +00:00
|
|
|
mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(walls[i].picnum));
|
2006-02-24 04:48:15 +00:00
|
|
|
pic = TexMan.GetTexture (tnam, FTexture::TEX_Build);
|
About a week's worth of changes here. As a heads-up, I wouldn't be
surprised if this doesn't build in Linux right now. The CMakeLists.txt
were checked with MinGW and NMake, but how they fair under Linux is an
unknown to me at this time.
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
- Added the gdtoa package from netlib's fp library so that ZDoom's printf-style
formatting can be entirely independant of the CRT.
SVN r1082 (trunk)
2008-07-23 04:57:26 +00:00
|
|
|
mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(walls[i].overpicnum));
|
2006-02-24 04:48:15 +00:00
|
|
|
overpic = TexMan.GetTexture (tnam, FTexture::TEX_Build);
|
|
|
|
|
|
|
|
walls[i].x = LittleLong(walls[i].x);
|
|
|
|
walls[i].y = LittleLong(walls[i].y);
|
|
|
|
walls[i].point2 = LittleShort(walls[i].point2);
|
|
|
|
walls[i].cstat = LittleShort(walls[i].cstat);
|
|
|
|
walls[i].nextwall = LittleShort(walls[i].nextwall);
|
|
|
|
walls[i].nextsector = LittleShort(walls[i].nextsector);
|
|
|
|
|
2008-03-21 17:35:49 +00:00
|
|
|
sides[i].SetTextureXOffset(walls[i].xpanning << FRACBITS);
|
|
|
|
sides[i].SetTextureYOffset(walls[i].ypanning << FRACBITS);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2008-03-21 17:35:49 +00:00
|
|
|
sides[i].SetTexture(side_t::top, pic);
|
|
|
|
sides[i].SetTexture(side_t::bottom, pic);
|
2006-02-24 04:48:15 +00:00
|
|
|
if (walls[i].nextsector < 0 || (walls[i].cstat & 32))
|
|
|
|
{
|
2008-03-21 17:35:49 +00:00
|
|
|
sides[i].SetTexture(side_t::mid, pic);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else if (walls[i].cstat & 16)
|
|
|
|
{
|
2008-03-21 17:35:49 +00:00
|
|
|
sides[i].SetTexture(side_t::mid, overpic);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-06-15 18:36:26 +00:00
|
|
|
sides[i].SetTexture(side_t::mid, FNullTextureID());
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sides[i].TexelLength = walls[i].xrepeat * 8;
|
2010-03-18 02:21:01 +00:00
|
|
|
sides[i].SetTextureYScale(walls[i].yrepeat << (FRACBITS - 3));
|
|
|
|
sides[i].SetTextureXScale(FRACUNIT);
|
2008-06-14 15:26:16 +00:00
|
|
|
sides[i].SetLight(SHADE2LIGHT(walls[i].shade));
|
2006-02-24 04:48:15 +00:00
|
|
|
sides[i].Flags = WALLF_ABSLIGHTING;
|
|
|
|
sides[i].RightSide = walls[i].point2;
|
|
|
|
sides[walls[i].point2].LeftSide = i;
|
|
|
|
|
|
|
|
if (walls[i].nextwall >= 0 && walls[i].nextwall <= i)
|
|
|
|
{
|
2009-09-06 18:19:28 +00:00
|
|
|
sides[i].linedef = sides[walls[i].nextwall].linedef;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-09-06 18:19:28 +00:00
|
|
|
sides[i].linedef = (line_t*)(intptr_t)(numlines++);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set line properties that Doom doesn't store per-sidedef
|
|
|
|
lines = new line_t[numlines];
|
|
|
|
memset (lines, 0, numlines*sizeof(line_t));
|
|
|
|
|
|
|
|
for (i = 0, j = -1; i < numwalls; ++i)
|
|
|
|
{
|
|
|
|
if (walls[i].nextwall >= 0 && walls[i].nextwall <= i)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-09-06 18:19:28 +00:00
|
|
|
j = int(intptr_t(sides[i].linedef));
|
2009-09-06 20:45:56 +00:00
|
|
|
lines[j].sidedef[0] = (side_t*)(intptr_t)i;
|
|
|
|
lines[j].sidedef[1] = (side_t*)(intptr_t)walls[i].nextwall;
|
2006-02-24 04:48:15 +00:00
|
|
|
lines[j].v1 = FindVertex (walls[i].x, walls[i].y);
|
|
|
|
lines[j].v2 = FindVertex (walls[walls[i].point2].x, walls[walls[i].point2].y);
|
|
|
|
lines[j].frontsector = sides[i].sector;
|
2006-05-09 21:30:31 +00:00
|
|
|
lines[j].flags |= ML_WRAP_MIDTEX;
|
2006-02-24 04:48:15 +00:00
|
|
|
if (walls[i].nextsector >= 0)
|
|
|
|
{
|
|
|
|
lines[j].backsector = sectors + walls[i].nextsector;
|
|
|
|
lines[j].flags |= ML_TWOSIDED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lines[j].backsector = NULL;
|
|
|
|
}
|
|
|
|
P_AdjustLine (&lines[j]);
|
|
|
|
if (walls[i].cstat & 128)
|
|
|
|
{
|
|
|
|
if (walls[i].cstat & 512)
|
|
|
|
{
|
2008-05-02 10:55:48 +00:00
|
|
|
lines[j].Alpha = FRACUNIT/3;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-05-02 10:55:48 +00:00
|
|
|
lines[j].Alpha = FRACUNIT*2/3;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (walls[i].cstat & 1)
|
|
|
|
{
|
|
|
|
lines[j].flags |= ML_BLOCKING;
|
|
|
|
}
|
|
|
|
if (walls[i].nextwall < 0)
|
|
|
|
{
|
|
|
|
if (walls[i].cstat & 4)
|
|
|
|
{
|
|
|
|
lines[j].flags |= ML_DONTPEGBOTTOM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (walls[i].cstat & 4)
|
|
|
|
{
|
|
|
|
lines[j].flags |= ML_DONTPEGTOP;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lines[j].flags |= ML_DONTPEGBOTTOM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (walls[i].cstat & 64)
|
|
|
|
{
|
|
|
|
lines[j].flags |= ML_BLOCKEVERYTHING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finish setting sector properties that depend on walls
|
|
|
|
for (i = 0; i < numsectors; ++i, ++bsec)
|
|
|
|
{
|
|
|
|
SlopeWork slope;
|
|
|
|
|
|
|
|
slope.wal = &walls[bsec->wallptr];
|
|
|
|
slope.wal2 = &walls[slope.wal->point2];
|
|
|
|
slope.dx = slope.wal2->x - slope.wal->x;
|
|
|
|
slope.dy = slope.wal2->y - slope.wal->y;
|
|
|
|
slope.i = long (sqrt ((double)(slope.dx*slope.dx+slope.dy*slope.dy))) << 5;
|
|
|
|
if (slope.i == 0)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ((bsec->floorstat & 2) && (bsec->floorheinum != 0))
|
|
|
|
{ // floor is sloped
|
|
|
|
slope.heinum = -LittleShort(bsec->floorheinum);
|
|
|
|
slope.z[0] = slope.z[1] = slope.z[2] = -bsec->floorz;
|
|
|
|
CalcPlane (slope, sectors[i].floorplane);
|
|
|
|
}
|
|
|
|
if ((bsec->ceilingstat & 2) && (bsec->ceilingheinum != 0))
|
|
|
|
{ // ceiling is sloped
|
|
|
|
slope.heinum = -LittleShort(bsec->ceilingheinum);
|
|
|
|
slope.z[0] = slope.z[1] = slope.z[2] = -bsec->ceilingz;
|
|
|
|
CalcPlane (slope, sectors[i].ceilingplane);
|
|
|
|
}
|
2009-09-06 18:19:28 +00:00
|
|
|
int linenum = int(intptr_t(sides[bsec->wallptr].linedef));
|
2009-09-06 20:45:56 +00:00
|
|
|
int sidenum = int(intptr_t(lines[linenum].sidedef[1]));
|
2006-02-24 04:48:15 +00:00
|
|
|
if (bsec->floorstat & 64)
|
|
|
|
{ // floor is aligned to first wall
|
2011-07-05 13:33:02 +00:00
|
|
|
P_AlignFlat (linenum, sidenum == bsec->wallptr, 0);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
if (bsec->ceilingstat & 64)
|
|
|
|
{ // ceiling is aligned to first wall
|
2011-07-05 13:33:02 +00:00
|
|
|
P_AlignFlat (linenum, sidenum == bsec->wallptr, 0);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
2010-03-18 02:09:08 +00:00
|
|
|
for (i = 0; i < numlines; i++)
|
2009-09-06 18:19:28 +00:00
|
|
|
{
|
2010-03-18 02:09:08 +00:00
|
|
|
intptr_t front = intptr_t(lines[i].sidedef[0]);
|
|
|
|
intptr_t back = intptr_t(lines[i].sidedef[1]);
|
|
|
|
lines[i].sidedef[0] = front >= 0 ? &sides[front] : NULL;
|
|
|
|
lines[i].sidedef[1] = back >= 0 ? &sides[back] : NULL;
|
2009-09-06 18:19:28 +00:00
|
|
|
}
|
2010-03-18 02:09:08 +00:00
|
|
|
for (i = 0; i < numsides; i++)
|
2009-09-06 20:45:56 +00:00
|
|
|
{
|
2010-03-18 02:09:08 +00:00
|
|
|
assert(sides[i].sector != NULL);
|
|
|
|
sides[i].linedef = &lines[intptr_t(sides[i].linedef)];
|
2009-09-06 20:45:56 +00:00
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// LoadSprites
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
2010-03-18 05:01:10 +00:00
|
|
|
static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites,
|
|
|
|
sectortype *bsectors, FMapThing *mapthings)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
|
2014-07-30 00:45:04 +00:00
|
|
|
memset(mapthings, 0, sizeof(*mapthings)*numsprites);
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
for (int i = 0; i < numsprites; ++i)
|
|
|
|
{
|
|
|
|
mapthings[count].thingid = 0;
|
2008-05-08 08:06:26 +00:00
|
|
|
mapthings[count].x = (sprites[i].x << 12);
|
|
|
|
mapthings[count].y = -(sprites[i].y << 12);
|
|
|
|
mapthings[count].z = (bsectors[sprites[i].sectnum].floorz - sprites[i].z) << 8;
|
2006-02-24 04:48:15 +00:00
|
|
|
mapthings[count].angle = (((2048-sprites[i].ang) & 2047) * 360) >> 11;
|
2008-05-11 21:16:32 +00:00
|
|
|
mapthings[count].ClassFilter = 0xffff;
|
|
|
|
mapthings[count].SkillFilter = 0xffff;
|
|
|
|
mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH;
|
2006-02-24 04:48:15 +00:00
|
|
|
mapthings[count].special = 0;
|
2013-08-09 14:25:16 +00:00
|
|
|
mapthings[count].gravity = FRACUNIT;
|
2014-07-30 00:45:04 +00:00
|
|
|
mapthings[count].RenderStyle = STYLE_Count;
|
|
|
|
mapthings[count].alpha = -1;
|
|
|
|
mapthings[count].health = -1;
|
2015-11-29 10:28:26 +00:00
|
|
|
mapthings[count].FloatbobPhase = -1;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2010-03-18 05:01:10 +00:00
|
|
|
if (xsprites != NULL && sprites[i].lotag == 710)
|
|
|
|
{ // Blood ambient sound
|
|
|
|
mapthings[count].args[0] = xsprites[i].Data3;
|
2014-07-30 01:47:01 +00:00
|
|
|
// I am totally guessing about the volume level. 50 seems to be a pretty
|
2010-03-18 05:01:10 +00:00
|
|
|
// typical value for Blood's standard maps, so I assume it's 100-based.
|
2010-03-18 21:09:23 +00:00
|
|
|
mapthings[count].args[1] = xsprites[i].Data4;
|
2010-03-18 05:01:10 +00:00
|
|
|
mapthings[count].args[2] = xsprites[i].Data1;
|
|
|
|
mapthings[count].args[3] = xsprites[i].Data2;
|
2015-04-04 08:25:01 +00:00
|
|
|
mapthings[count].EdNum = 14065;
|
2010-03-18 05:01:10 +00:00
|
|
|
}
|
2014-07-30 02:39:05 +00:00
|
|
|
else if (xsprites != NULL && sprites[i].lotag == 1)
|
|
|
|
{ // Blood player start
|
|
|
|
if (xsprites[i].Data1 < 4)
|
2015-04-04 08:25:01 +00:00
|
|
|
mapthings[count].EdNum= 1 + xsprites[i].Data1;
|
2014-07-30 02:39:05 +00:00
|
|
|
else
|
2015-04-04 08:25:01 +00:00
|
|
|
mapthings[count].EdNum = 4001 + xsprites[i].Data1 - 4;
|
2014-07-30 02:39:05 +00:00
|
|
|
}
|
|
|
|
else if (xsprites != NULL && sprites[i].lotag == 2)
|
|
|
|
{ // Bloodbath start
|
2015-04-04 08:25:01 +00:00
|
|
|
mapthings[count].EdNum = 11;
|
2014-07-30 02:39:05 +00:00
|
|
|
}
|
2010-03-18 05:01:10 +00:00
|
|
|
else
|
|
|
|
{
|
2014-07-31 23:22:33 +00:00
|
|
|
if (sprites[i].cstat & 32768) continue;
|
2010-03-18 05:01:10 +00:00
|
|
|
if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue;
|
|
|
|
|
2015-04-04 08:25:01 +00:00
|
|
|
mapthings[count].EdNum = 9988;
|
2014-08-01 03:18:08 +00:00
|
|
|
mapthings[count].args[0] = sprites[i].picnum;
|
2010-03-18 05:01:10 +00:00
|
|
|
mapthings[count].args[2] = sprites[i].xrepeat;
|
|
|
|
mapthings[count].args[3] = sprites[i].yrepeat;
|
2014-08-01 03:18:08 +00:00
|
|
|
mapthings[count].args[4] = sprites[i].cstat;
|
2010-03-18 05:01:10 +00:00
|
|
|
}
|
2015-04-04 08:25:01 +00:00
|
|
|
mapthings[count].info = DoomEdMap.CheckKey(mapthings[count].EdNum);
|
2006-02-24 04:48:15 +00:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FindVertex
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
vertex_t *FindVertex (fixed_t x, fixed_t y)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
x <<= 12;
|
|
|
|
y = -(y << 12);
|
|
|
|
|
|
|
|
for (i = 0; i < numvertexes; ++i)
|
|
|
|
{
|
|
|
|
if (vertexes[i].x == x && vertexes[i].y == y)
|
|
|
|
{
|
|
|
|
return &vertexes[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vertexes[i].x = x;
|
|
|
|
vertexes[i].y = y;
|
|
|
|
numvertexes++;
|
|
|
|
return &vertexes[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// CreateStartSpot
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
2008-05-08 08:06:26 +00:00
|
|
|
static void CreateStartSpot (fixed_t *pos, FMapThing *start)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
short angle = LittleShort(*(WORD *)(&pos[3]));
|
2015-04-04 22:05:38 +00:00
|
|
|
FMapThing mt = { 0, };
|
|
|
|
|
|
|
|
mt.x = LittleLong(pos[0])<<12;
|
|
|
|
mt.y = (-LittleLong(pos[1]))<<12;
|
|
|
|
mt.angle = short(Scale((2048-angle)&2047, 360, 2048));
|
|
|
|
mt.info = DoomEdMap.CheckKey(1);
|
|
|
|
mt.EdNum = 1;
|
|
|
|
mt.flags = 7|MTF_SINGLE|224;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
*start = mt;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// CalcPlane
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
static void CalcPlane (SlopeWork &slope, secplane_t &plane)
|
|
|
|
{
|
2016-02-11 19:01:12 +00:00
|
|
|
TVector3<double> pt[3];
|
2006-02-24 04:48:15 +00:00
|
|
|
long j;
|
|
|
|
|
|
|
|
slope.x[0] = slope.wal->x; slope.y[0] = slope.wal->y;
|
|
|
|
slope.x[1] = slope.wal2->x; slope.y[1] = slope.wal2->y;
|
|
|
|
if (slope.dx == 0)
|
|
|
|
{
|
|
|
|
slope.x[2] = slope.x[0] + 64;
|
|
|
|
slope.y[2] = slope.y[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
slope.x[2] = slope.x[0];
|
|
|
|
slope.y[2] = slope.y[0] + 64;
|
|
|
|
}
|
|
|
|
j = DMulScale3 (slope.dx, slope.y[2]-slope.wal->y,
|
|
|
|
-slope.dy, slope.x[2]-slope.wal->x);
|
|
|
|
slope.z[2] += Scale (slope.heinum, j, slope.i);
|
|
|
|
|
2016-02-11 19:01:12 +00:00
|
|
|
pt[0] = TVector3<double>(slope.dx, -slope.dy, 0);
|
|
|
|
pt[1] = TVector3<double>(slope.x[2] - slope.x[0], slope.y[0] - slope.y[2], (slope.z[2] - slope.z[0]) / 16);
|
2007-01-19 02:00:39 +00:00
|
|
|
pt[2] = (pt[0] ^ pt[1]).Unit();
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2007-01-19 02:00:39 +00:00
|
|
|
if ((pt[2][2] < 0 && plane.c > 0) || (pt[2][2] > 0 && plane.c < 0))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2007-01-19 02:00:39 +00:00
|
|
|
pt[2] = -pt[2];
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
2016-02-11 19:01:12 +00:00
|
|
|
plane.a = FLOAT2FIXED(pt[2][0]);
|
|
|
|
plane.b = FLOAT2FIXED(pt[2][1]);
|
|
|
|
plane.c = FLOAT2FIXED(pt[2][2]);
|
|
|
|
plane.ic = DivScale32(1, plane.c);
|
2006-02-24 04:48:15 +00:00
|
|
|
plane.d = -TMulScale8
|
|
|
|
(plane.a, slope.x[0]<<4, plane.b, (-slope.y[0])<<4, plane.c, slope.z[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Decrypt
|
|
|
|
//
|
2006-06-15 03:31:19 +00:00
|
|
|
// Note that this is different from the general RFF encryption.
|
|
|
|
//
|
2006-02-24 04:48:15 +00:00
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
static void Decrypt (void *to_, const void *from_, int len, int key)
|
|
|
|
{
|
|
|
|
BYTE *to = (BYTE *)to_;
|
|
|
|
const BYTE *from = (const BYTE *)from_;
|
|
|
|
|
2006-06-15 03:31:19 +00:00
|
|
|
for (int i = 0; i < len; ++i, ++key)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2006-06-15 03:31:19 +00:00
|
|
|
to[i] = from[i] ^ key;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Just an actor to make the Build sprites show up. It doesn't do anything
|
|
|
|
// with them other than display them.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
class ACustomSprite : public AActor
|
|
|
|
{
|
2008-08-08 16:16:40 +00:00
|
|
|
DECLARE_CLASS (ACustomSprite, AActor);
|
2006-02-24 04:48:15 +00:00
|
|
|
public:
|
|
|
|
void BeginPlay ();
|
|
|
|
};
|
|
|
|
|
2008-08-08 16:16:40 +00:00
|
|
|
IMPLEMENT_CLASS (ACustomSprite)
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
void ACustomSprite::BeginPlay ()
|
|
|
|
{
|
2008-06-15 18:36:26 +00:00
|
|
|
char name[9];
|
2006-02-24 04:48:15 +00:00
|
|
|
Super::BeginPlay ();
|
2008-06-15 18:36:26 +00:00
|
|
|
|
2014-08-01 03:18:08 +00:00
|
|
|
mysnprintf (name, countof(name), "BTIL%04d", args[0] & 0xffff);
|
2008-06-15 18:36:26 +00:00
|
|
|
picnum = TexMan.GetTexture (name, FTexture::TEX_Build);
|
|
|
|
|
2006-11-14 16:54:02 +00:00
|
|
|
scaleX = args[2] * (FRACUNIT/64);
|
|
|
|
scaleY = args[3] * (FRACUNIT/64);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2014-08-01 03:18:08 +00:00
|
|
|
int cstat = args[4];
|
|
|
|
if (cstat & 2)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
RenderStyle = STYLE_Translucent;
|
2014-08-01 03:18:08 +00:00
|
|
|
alpha = (cstat & 512) ? TRANSLUC66 : TRANSLUC33;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
2014-08-01 03:18:08 +00:00
|
|
|
if (cstat & 4)
|
2006-02-24 04:48:15 +00:00
|
|
|
renderflags |= RF_XFLIP;
|
2014-08-01 03:18:08 +00:00
|
|
|
if (cstat & 8)
|
2006-02-24 04:48:15 +00:00
|
|
|
renderflags |= RF_YFLIP;
|
2014-12-21 01:11:39 +00:00
|
|
|
|
2014-08-01 03:18:08 +00:00
|
|
|
// set face/wall/floor flags
|
2015-04-04 16:40:43 +00:00
|
|
|
renderflags |= ActorRenderFlags::FromInt (((cstat >> 4) & 3) << 12);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|