mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 00:41:55 +00:00
- use a TArrayView to store the wall references in a sector.
This is a lot more scripting friendly than hacking around the indices.
This commit is contained in:
parent
9a676ffba6
commit
bfae5ce1bc
10 changed files with 113 additions and 124 deletions
|
@ -95,8 +95,9 @@ void sectortype::allocX()
|
|||
|
||||
static void ReadSectorV7(FileReader& fr, sectortype& sect)
|
||||
{
|
||||
sect.wallptr = fr.ReadInt16();
|
||||
sect.wallnum = fr.ReadInt16();
|
||||
int wallptr = fr.ReadInt16();
|
||||
int wallnum = fr.ReadInt16();
|
||||
sect.walls.Set(&wall[wallptr], wallnum);
|
||||
int c = fr.ReadInt32();
|
||||
int f = fr.ReadInt32();
|
||||
sect.setzfrommap(c, f);
|
||||
|
@ -123,8 +124,9 @@ static void ReadSectorV7(FileReader& fr, sectortype& sect)
|
|||
|
||||
static void ReadSectorV6(FileReader& fr, sectortype& sect)
|
||||
{
|
||||
sect.wallptr = fr.ReadUInt16();
|
||||
sect.wallnum = fr.ReadUInt16();
|
||||
int wallptr = fr.ReadInt16();
|
||||
int wallnum = fr.ReadInt16();
|
||||
sect.walls.Set(&wall[wallptr], wallnum);
|
||||
sect.ceilingpicnum = fr.ReadUInt16();
|
||||
sect.floorpicnum = fr.ReadUInt16();
|
||||
sect.ceilingheinum = clamp(fr.ReadInt16() << 5, -32768, 32767);
|
||||
|
@ -151,8 +153,9 @@ static void ReadSectorV6(FileReader& fr, sectortype& sect)
|
|||
|
||||
static void ReadSectorV5(FileReader& fr, sectortype& sect)
|
||||
{
|
||||
sect.wallptr = fr.ReadInt16();
|
||||
sect.wallnum = fr.ReadInt16();
|
||||
int wallptr = fr.ReadInt16();
|
||||
int wallnum = fr.ReadInt16();
|
||||
sect.walls.Set(&wall[wallptr], wallnum);
|
||||
sect.ceilingpicnum = fr.ReadUInt16();
|
||||
sect.floorpicnum = fr.ReadUInt16();
|
||||
sect.ceilingheinum = clamp(fr.ReadInt16() << 5, -32768, 32767);
|
||||
|
@ -426,8 +429,7 @@ void fixSectors()
|
|||
// Note: we do not have the 'sector' index initialized here, it would not be helpful anyway for this fix.
|
||||
while (wp != wall.Data() && wp[-1].twoSided() && wp[-1].nextWall()->nextWall() == &wp[-1] && wp[-1].nextWall()->nextSector() == §)
|
||||
{
|
||||
sect.wallptr--;
|
||||
sect.wallnum++;
|
||||
sect.walls.Set(sect.walls.Data() - 1, sect.walls.Size() + 1);
|
||||
wp--;
|
||||
}
|
||||
}
|
||||
|
@ -755,8 +757,8 @@ void setWallSectors()
|
|||
auto sect = §or[i];
|
||||
auto nextsect = §or[i + 1];
|
||||
|
||||
int sectstart = sect->wall_index();
|
||||
int nextsectstart = nextsect->wall_index();
|
||||
int sectstart = wallindex(sect->firstWall());
|
||||
int nextsectstart = wallindex(sect->firstWall());
|
||||
|
||||
if (sectstart < nextsectstart && sectstart + sect->wall_count() > nextsectstart)
|
||||
{
|
||||
|
@ -765,8 +767,8 @@ void setWallSectors()
|
|||
int checkend = sectstart + sect->wall_count();
|
||||
|
||||
// for now assign the walls to the first sector. Final decisions are made below.
|
||||
nextsect->wallnum -= checkend - checkstart;
|
||||
nextsect->wallptr = checkend;
|
||||
nextsectstart = checkend;
|
||||
nextsect->walls.Set(&wall[nextsectstart], nextsect->walls.Size() - (checkend - checkstart));
|
||||
|
||||
auto belongs = [](int wal, int first, int last, int firstwal)
|
||||
{
|
||||
|
@ -782,19 +784,20 @@ void setWallSectors()
|
|||
while (checkstart < checkend && belongs(checkstart, sectstart, checkstart, checkstart))
|
||||
checkstart++;
|
||||
|
||||
sect->wallnum = checkstart - sectstart;
|
||||
sect->walls.Set(sect->firstWall(), checkstart - sectstart);
|
||||
|
||||
while (checkstart < checkend && belongs(checkend - 1, checkend, nextsectstart + nextsect->wall_count(), checkstart))
|
||||
checkend--;
|
||||
|
||||
nextsect->wallnum += nextsectstart - checkend;
|
||||
nextsect->wallptr = nextsectstart = checkend;
|
||||
int cnt = nextsect->walls.Size() - (nextsectstart - checkend);
|
||||
nextsectstart = checkend;
|
||||
nextsect->walls.Set(&wall[nextsectstart], cnt);
|
||||
|
||||
if (nextsectstart > sectstart + sect->wall_count())
|
||||
{
|
||||
// If there's a gap, assign to the first sector. In this case we may only guess.
|
||||
Printf("Wall range %d - %d referenced by sectors %d and %d\n", sectstart + sect->wall_count(), nextsectstart - 1, i, i + 1);
|
||||
sect->wallnum = nextsectstart - sectstart;
|
||||
sect->walls.Set(sect->firstWall(), nextsectstart - sectstart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,7 +210,86 @@ BEGIN_BLD_NS
|
|||
END_BLD_NS
|
||||
|
||||
class DCoreActor;
|
||||
struct walltype;
|
||||
struct sectortype;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// internal wall struct - no longer identical with on-disk format
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
struct walltype
|
||||
{
|
||||
DVector2 pos;
|
||||
|
||||
vec2_t wall_int_pos() const { return vec2_t(int(pos.X * worldtoint), int(pos.Y * worldtoint)); };
|
||||
vec2_t int_delta() const { return point2Wall()->wall_int_pos() - wall_int_pos(); }
|
||||
|
||||
void setPosFromMap(int x, int y) { pos = { x * maptoworld, y * maptoworld }; }
|
||||
|
||||
int32_t point2;
|
||||
int32_t nextwall;
|
||||
int32_t sector; // Build never had this...
|
||||
int32_t nextsector;
|
||||
|
||||
// Again, panning fields extended for interpolation.
|
||||
float xpan_;
|
||||
float ypan_;
|
||||
|
||||
EWallFlags cstat;
|
||||
int16_t picnum;
|
||||
int16_t overpicnum;
|
||||
union { int16_t lotag, type; }; // type is for Blood
|
||||
int16_t hitag;
|
||||
int16_t extra;
|
||||
|
||||
int8_t shade;
|
||||
uint8_t pal;
|
||||
uint8_t xrepeat;
|
||||
uint8_t yrepeat;
|
||||
|
||||
// extensions not from the binary map format.
|
||||
angle_t clipangle;
|
||||
double length; // cached value to avoid calling sqrt repeatedly.
|
||||
|
||||
uint16_t portalnum;
|
||||
uint8_t portalflags;
|
||||
uint8_t lengthflags;
|
||||
|
||||
// Blood is the only game which extends the wall struct.
|
||||
Blood::XWALL* _xw;
|
||||
DVector2 baseWall;
|
||||
|
||||
int xpan() const { return int(xpan_); }
|
||||
int ypan() const { return int(ypan_); }
|
||||
void setxpan(float add) { xpan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets
|
||||
void setypan(float add) { ypan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets
|
||||
void addxpan(float add) { xpan_ = fmodf(xpan_ + add + 512, 256); } // +512 is for handling negative offsets
|
||||
void addypan(float add) { ypan_ = fmodf(ypan_ + add + 512, 256); } // +512 is for handling negative offsets
|
||||
sectortype* nextSector() const;
|
||||
sectortype* sectorp() const;
|
||||
walltype* nextWall() const;
|
||||
walltype* lastWall(bool fast = true) const;
|
||||
walltype* point2Wall() const;
|
||||
DVector2 delta() const { return point2Wall()->pos - pos; }
|
||||
DVector2 center() const { return(point2Wall()->pos + pos) / 2; }
|
||||
DAngle normalAngle() const { return delta().Angle() + DAngle90; }
|
||||
bool twoSided() const { return nextsector >= 0; }
|
||||
double Length();
|
||||
void calcLength(); // this is deliberately not inlined and stored in a file where it can't be found at compile time.
|
||||
void move(const DVector2& vec)
|
||||
{
|
||||
pos = vec;
|
||||
moved();
|
||||
}
|
||||
|
||||
void moved();
|
||||
|
||||
Blood::XWALL& xw() const { return *_xw; }
|
||||
bool hasX() const { return _xw != nullptr; }
|
||||
void allocX();
|
||||
};
|
||||
|
||||
// enable for running a compile-check to ensure that renderer-critical variables are not being written to directly.
|
||||
//#define SECTOR_HACKJOB
|
||||
|
@ -227,7 +306,8 @@ struct sectortype
|
|||
// Fields were reordered by size, some also enlarged.
|
||||
DCoreActor* firstEntry, * lastEntry;
|
||||
|
||||
int32_t wallptr;
|
||||
TArrayView<walltype> walls;
|
||||
|
||||
#ifdef SECTOR_HACKJOB
|
||||
// Debug hack job for finding all places where ceilingz and floorz get written to.
|
||||
// If the engine does not compile with this block on, we got a problem.
|
||||
|
@ -259,7 +339,6 @@ struct sectortype
|
|||
float floorxpan_;
|
||||
float floorypan_;
|
||||
|
||||
int16_t wallnum;
|
||||
ESectorFlags ceilingstat;
|
||||
ESectorFlags floorstat;
|
||||
int16_t ceilingpicnum;
|
||||
|
@ -348,10 +427,9 @@ struct sectortype
|
|||
void setfloorslope(int heinum) { floorheinum = heinum; if (heinum) floorstat |= CSTAT_SECTOR_SLOPE; else floorstat &= ~CSTAT_SECTOR_SLOPE; }
|
||||
int getfloorslope() const { return floorstat & CSTAT_SECTOR_SLOPE ? floorheinum : 0; }
|
||||
int getceilingslope() const { return ceilingstat & CSTAT_SECTOR_SLOPE ? ceilingheinum : 0; }
|
||||
walltype* firstWall() const;
|
||||
walltype* lastWall() const;
|
||||
int wall_index() const { return wallptr; }
|
||||
int wall_count() const { return wallnum; }
|
||||
walltype* firstWall() const { return walls.Data(); }
|
||||
walltype* lastWall() const { return &walls.Last(); }
|
||||
int wall_count() const { return walls.Size(); }
|
||||
|
||||
|
||||
Blood::XSECTOR& xs() const { return *_xs; }
|
||||
|
@ -362,84 +440,6 @@ struct sectortype
|
|||
bool hasU() const { return u_defined; }
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// internal wall struct - no longer identical with on-disk format
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
struct walltype
|
||||
{
|
||||
DVector2 pos;
|
||||
|
||||
vec2_t wall_int_pos() const { return vec2_t(int(pos.X * worldtoint), int(pos.Y * worldtoint)); };
|
||||
vec2_t int_delta() const { return point2Wall()->wall_int_pos() - wall_int_pos(); }
|
||||
|
||||
void setPosFromMap(int x, int y) { pos = { x * maptoworld, y * maptoworld }; }
|
||||
|
||||
int32_t point2;
|
||||
int32_t nextwall;
|
||||
int32_t sector; // Build never had this...
|
||||
int32_t nextsector;
|
||||
|
||||
// Again, panning fields extended for interpolation.
|
||||
float xpan_;
|
||||
float ypan_;
|
||||
|
||||
EWallFlags cstat;
|
||||
int16_t picnum;
|
||||
int16_t overpicnum;
|
||||
union { int16_t lotag, type; }; // type is for Blood
|
||||
int16_t hitag;
|
||||
int16_t extra;
|
||||
|
||||
int8_t shade;
|
||||
uint8_t pal;
|
||||
uint8_t xrepeat;
|
||||
uint8_t yrepeat;
|
||||
|
||||
// extensions not from the binary map format.
|
||||
angle_t clipangle;
|
||||
double length; // cached value to avoid calling sqrt repeatedly.
|
||||
|
||||
uint16_t portalnum;
|
||||
uint8_t portalflags;
|
||||
uint8_t lengthflags;
|
||||
|
||||
// Blood is the only game which extends the wall struct.
|
||||
Blood::XWALL* _xw;
|
||||
DVector2 baseWall;
|
||||
|
||||
int xpan() const { return int(xpan_); }
|
||||
int ypan() const { return int(ypan_); }
|
||||
void setxpan(float add) { xpan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets
|
||||
void setypan(float add) { ypan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets
|
||||
void addxpan(float add) { xpan_ = fmodf(xpan_ + add + 512, 256); } // +512 is for handling negative offsets
|
||||
void addypan(float add) { ypan_ = fmodf(ypan_ + add + 512, 256); } // +512 is for handling negative offsets
|
||||
sectortype* nextSector() const;
|
||||
sectortype* sectorp() const;
|
||||
walltype* nextWall() const;
|
||||
walltype* lastWall(bool fast = true) const;
|
||||
walltype* point2Wall() const;
|
||||
DVector2 delta() const { return point2Wall()->pos - pos; }
|
||||
DVector2 center() const { return(point2Wall()->pos + pos) / 2; }
|
||||
DAngle normalAngle() const { return delta().Angle() + DAngle90; }
|
||||
bool twoSided() const { return nextsector >= 0; }
|
||||
double Length();
|
||||
void calcLength(); // this is deliberately not inlined and stored in a file where it can't be found at compile time.
|
||||
void move(const DVector2& vec)
|
||||
{
|
||||
pos = vec;
|
||||
moved();
|
||||
}
|
||||
|
||||
void moved();
|
||||
|
||||
Blood::XWALL& xw() const { return *_xw; }
|
||||
bool hasX() const { return _xw != nullptr; }
|
||||
void allocX();
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// internal sprite struct - no longer identical with on-disk format
|
||||
|
@ -597,16 +597,6 @@ inline walltype* walltype::point2Wall() const
|
|||
return &::wall[point2]; // cannot be -1 in a proper map.
|
||||
}
|
||||
|
||||
inline walltype* sectortype::firstWall() const
|
||||
{
|
||||
return &wall[wallptr]; // cannot be -1 in a proper map
|
||||
}
|
||||
|
||||
inline walltype* sectortype::lastWall() const
|
||||
{
|
||||
return &wall[wallptr + wallnum - 1]; // cannot be -1 in a proper map
|
||||
}
|
||||
|
||||
inline void walltype::moved()
|
||||
{
|
||||
lengthflags = 3;
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "maptypes.h"
|
||||
#include "hw_sections.h"
|
||||
#include "mapinfo.h"
|
||||
#include "gamefuncs.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -124,7 +125,7 @@ DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SplitSector)
|
|||
|
||||
if (sectornum < sector.Size())
|
||||
{
|
||||
int sectstart = sector[sectornum].wall_index();
|
||||
int sectstart = wallindex(sector[sectornum].firstWall());
|
||||
if (firstwall >= sectstart && firstwall < sectstart + sector[sectornum].wall_count() &&
|
||||
secondwall >= sectstart && secondwall < sectstart + sector[sectornum].wall_count())
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ static void CollectLoops(TArray<loopcollect>& sectors)
|
|||
int count = 0;
|
||||
for (unsigned i = 0; i < sector.Size(); i++)
|
||||
{
|
||||
int first = sector[i].wall_index();
|
||||
int first = wallindex(sector[i].firstWall());
|
||||
int last = first + sector[i].wall_count();
|
||||
sectors.Reserve(1);
|
||||
sectors.Last().bugged = 0;
|
||||
|
|
|
@ -458,8 +458,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sectortype &c, sectort
|
|||
{
|
||||
arc("firstentry", c.firstEntry)
|
||||
("lastentry", c.lastEntry)
|
||||
("wallptr", c.wallptr, def->wallptr)
|
||||
("wallnum", c.wallnum, def->wallnum)
|
||||
#ifndef SECTOR_HACKJOB // can't save these in test mode...
|
||||
("ceilingz", c.ceilingz, def->ceilingz)
|
||||
("floorz", c.floorz, def->floorz)
|
||||
|
|
|
@ -47,8 +47,7 @@ DEFINE_FIELD_NAMED_X(sectortype, sectortype, ceilingxpan_, ceilingxpan)
|
|||
DEFINE_FIELD_NAMED_X(sectortype, sectortype, ceilingypan_, ceilingypan)
|
||||
DEFINE_FIELD_NAMED_X(sectortype, sectortype, floorxpan_, floorxpan)
|
||||
DEFINE_FIELD_NAMED_X(sectortype, sectortype, floorypan_, floorypan)
|
||||
DEFINE_FIELD_X(sectortype, sectortype, wallptr)
|
||||
DEFINE_FIELD_X(sectortype, sectortype, wallnum)
|
||||
DEFINE_FIELD_UNSIZED(sectortype, sectortype, walls)
|
||||
DEFINE_FIELD_X(sectortype, sectortype, ceilingstat)
|
||||
DEFINE_FIELD_X(sectortype, sectortype, floorstat)
|
||||
DEFINE_FIELD_X(sectortype, sectortype, lotag)
|
||||
|
|
|
@ -253,8 +253,7 @@ void dbLoadMap(const char* pPath, DVector3& pos, short* pAngle, sectortype** cur
|
|||
{
|
||||
dbCrypt((char*)&load, sizeof(sectortypedisk), gMapRev * sizeof(sectortypedisk));
|
||||
}
|
||||
pSector->wallptr = LittleShort(load.wallptr);
|
||||
pSector->wallnum = LittleShort(load.wallnum);
|
||||
pSector->walls.Set(&wall[LittleShort(load.wallptr)], LittleShort(load.wallnum));
|
||||
pSector->setzfrommap(LittleLong(load.ceilingz), LittleLong(load.floorz));
|
||||
pSector->ceilingstat = ESectorFlags::FromInt(LittleShort(load.ceilingstat));
|
||||
pSector->floorstat = ESectorFlags::FromInt(LittleShort(load.floorstat));
|
||||
|
|
|
@ -1052,7 +1052,7 @@ void DoSector(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor,
|
|||
switch (lLabelID)
|
||||
{
|
||||
case SECTOR_WALLPTR:
|
||||
if (!bSet) SetGameVarID(lVar2, sectp->wall_index(), sActor, sPlayer);
|
||||
if (!bSet) SetGameVarID(lVar2, wallindex(sectp->firstWall()), sActor, sPlayer);
|
||||
break;
|
||||
case SECTOR_WALLNUM:
|
||||
if (!bSet) SetGameVarID(lVar2, sectp->wall_count(), sActor, sPlayer);
|
||||
|
|
|
@ -128,7 +128,7 @@ void feebtag(const DVector3& pos, sectortype* pSector, DExhumedActor **nSprite,
|
|||
{
|
||||
*nSprite = nullptr;
|
||||
|
||||
int startwall = pSector->wall_index();
|
||||
auto startwall = pSector->firstWall();
|
||||
|
||||
int nWalls = pSector->wall_count();
|
||||
|
||||
|
@ -166,7 +166,7 @@ void feebtag(const DVector3& pos, sectortype* pSector, DExhumedActor **nSprite,
|
|||
if (nWalls < -1)
|
||||
return;
|
||||
|
||||
pSector = wall[startwall].nextSector();
|
||||
pSector = startwall->nextSector();
|
||||
startwall++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,8 +123,7 @@ struct sectortype native
|
|||
native readonly float floorypan;
|
||||
native readonly double ceilingz, floorz;
|
||||
|
||||
native readonly int wallptr;
|
||||
native readonly int16 wallnum;
|
||||
native Array<@walltype> walls;
|
||||
native int16 ceilingstat;
|
||||
native int16 floorstat;
|
||||
//int16 ceilingpicnum;
|
||||
|
|
Loading…
Reference in a new issue