Talk:Reject

From DoomWiki.org

Revision as of 16:53, 18 September 2007 by 71.58.109.233 (talk)

When you extract the packed reject table into a file, using a program like DETH, it pads the hex output to the next highest multiple of 16 bytes.  For instance, the table for E1M1 is 968 = 16 × 60.5 bytes long, so 8 extra bytes are added to the dump.  I managed to figure out (using RMB) that they were all at the end.  They aren't zero.  They don't duplicate the first 8 bytes.  What are they?  Are they, for example, the first 8 bytes of the next lump?  (If so, does that mean that some of the padding occurs at the beginning of the list for other levels, depending on the absolute starting address of the reject lump?  Sheesh.)    Ryan W 21:16, 25 August 2007 (UTC)

Loading of reject from file is in lxdoom-1.10 p_setup.c:660
rejectmatrix = W_CacheLumpNum (lumpnum+ML_REJECT,PU_LEVEL);
W_CacheLumpNum allocates memory for a lump equal to the size of the lump as specified in the wad, and loads the lump into that memory. So this code doesn't care how much padding is on reject, or even if the reject table is at all properly sized for the wad.
Using of reject is in p_sight.c:294-348. excerpt:
s1 = (t1->subsector->sector - sectors);
s2 = (t2->subsector->sector - sectors);
pnum = s1*numsectors + s2;
bytenum = pnum>>3;
bitnum = 1 << (pnum&7);

// Check in REJECT table.
if (rejectmatrix[bytenum]&bitnum)
{
  sightcounts[0]++;

  // can't possibly be connected
  return false;	
}
This code simply calculates which which bit the desired reject result ought to be in, and reads that far into the table for the result. No padding anywhere inside the table is allowed. Padding at the end is ignored. If the reject table is too short, the function will simply read off the end into whatever garbage is in memory next. So the only nessecary padding is to fill up the last byte if numsect * numsect is not divisible by 8.
ZenNode 1.21 does the following. ZenReject.cpp:248-252
int noSectors  = level->SectorCount ();
int rejectSize = (( noSectors * noSectors ) + 7 ) / 8;

UINT8 *reject = new UINT8 [ rejectSize ];
memset ( reject, 0, rejectSize );
The code then proceeds to fill all bits corresponding to sector lookups with the calculated reject data, while leaving all other bits zero. The only padding ZenNode applies is the + 7, which simply rounds up to the next byte; if numsect * numsect is not divisible by 8, the division by 8 would truncate and leave no room for the spillovers into the last byte.
As far as your example case goes, I'd have to chalk it up to an error in Deth (which uses an earlier version of zennode I believe). The idbsp generated rejects in the original iwad also don't contain any extra padding. 71.58.109.233 21:53, 18 September 2007 (UTC)