================================================================================
Changes since Eternity Engine v3.33.33
================================================================================
--------------------------------------------------------------------------------
10/22/06

SoM improved the automap for use with linked portals.

Final commits are now being made for 3.33.50 release to mop up the last few
remaining minor issues and problems.

--------------------------------------------------------------------------------
10/19/06

Added a style guide for new programmers :)

--------------------------------------------------------------------------------
10/18/06

Fixed console command event responding for real, finally, by adding a new call
to G_KeyResponder(kac_cmd) in G_Responder. Joe added his SteamSpawn codepointer.
Sequence saving/loading is complete. SoM made a massive linked portals commit.

--------------------------------------------------------------------------------
10/17/06

Rewrote the dynamic credits screen to make it look really snazzy. Fixed a bug in
the abscenter text drawing code. Added a new separate ceiling sound origin for
sectors so that they can run two sound sequences when both the floor and ceiling
are affected by separate actions. Began sound sequence saving/loading code.
Finished polyobject sequence support.

--------------------------------------------------------------------------------
10/10/06

Added an optional vissprite limit.

--------------------------------------------------------------------------------
10/09/06

And the fun continues:

* Changed the ACS PRINTBOLD function to use FC_GOLD instead of FC_YELLOW. I keep
  making this mistake over and over in different parts of the source; you'd
  think I'd learn :P
  
* DEH strings replacement has been significantly improved simply by making the
  parser always compare strings against their original values instead of the
  newest value assigned to them by DeHackEd. I don't know why it didn't work
  this way to begin with, and I'd consider it a bug fix. fraggle helped out a
  bit by providing a weird DEH patch that was mostly broken without this tweak,
  and some advice on how to fix it.
  
* The DEH log file has been functionalized. The way it was done before was 
  simply terrible. Really, the whole parser is overdue for a rewrite, but that's
  pretty low-priority since I encourage the use of EDF over DEH/BEX.
  
* Several DEH parser bugs have been fixed, mainly dealing with the provision of
  invalid ammo or weapon indices.
  
* Added DEH_String function similar to the one used by Chocolate Doom. This lets
  the game engine get DEH/BEX strings using their BEX mnemonic instead of
  relying on a global variable. I've gone through and replaced almost all uses 
  of the global variables with calls to this function. I was also able to add a
  DEH_StringChanged function, which tells you whether or not a DEH/BEX patch has
  changed the value of a given string. This helped me fix a problem in the level
  name determination code where if DeHackEd was added, ALL levels would suddenly
  start to use the default DOOM level names. The proper thing to do is to enable
  default names only for maps that have actually had their name replaced :)
  
* Added BEX strings TITLEPIC, TITLE, CREDIT, ORDER, and DEMO1 - DEMO4. These
  allow DEH/BEX replacement of screen resource names in the title/demo sequence.
  TITLE is for Heretic/Hexen, btw.
  
--------------------------------------------------------------------------------
10/08/06

I'm getting an enormous amount of work done every day. Basically this is my
version of crunch mode :P

* DoomBarrel's correct_height was not correct :P  Somebody in the BOOM team
  didn't do their homework I guess, because a height of 28.0 actually is
  somewhat inside the top of the sprite. As a result, the map Barrels o' Fun
  was broken. The mancubus at the beginning could shoot fireballs to his heart's
  content and they would pass right through the barrels. Fixed it to be 34.0,
  which is much closer and causes the mancubus to blow up those barrels.
  
* Longtics demo support. This means that EE can now play cph's Doom v1.91 demos,
  and that new demos recorded with 3.33.50 or later will have full turning
  precision :)
  
* Fixed the intermission to kill all playing looped sounds, since otherwise 
  they continue until the end of the intermission.
  
* Started integrating joe's Hexen pillars code.

* Fixed the "sky is too low by 1 pixel" problem. It turns out the whole screen
  was off by half a pixel on average. This was due to the new mlook code. Why?
  finetangent is horrible and causes roundoff error, especially for the value
  at which your default pitch angle rests (I believe it is near an asymptote of
  the tangent function). As a result, EE now simply uses Doom's old method of
  setting the centery/centeryfrac variables when your pitch angle is zero,
  because in fact there's no need to do any of that extra, inaccurate calcu-
  lation when it's zero. This is an extremely small optimization on top of a
  needed bug fix ;)
  
* Removed sky stretching when playing old demos. Old demos have no mlook, and 
  thus they don't need sky stretching. Looks a lot better now IMO.
  
* Changed shadow text to use colormap 33 instead of 31, just to make sure that
  all the colors are mapped to true black :)  It looks about the same to me,
  though.

--------------------------------------------------------------------------------
10/03/06

Another big day; this work has brought 3.33.50 to the brink of release.

* Floor sequences are finished. They required some special consideration when
  dealing with delayed stairs. zdoom seems to leave the sequences running on
  such stair sectors, but I don't like that.

* Fixed a number of bugs in param stairs, corrected major mistakes in their
  documentation, and removed the "delay" parameter for sync'd stairs. Sync'd
  stairs cannot delay between steps; I have no idea what I was thinking when I
  added that parameter to those types...

* At long last, I found the bug in the zone heap introduced in BOOM when the
  engine is compiled with INSTRUMENTED defined and runs out of zone memory.
  VM blocks had their "extra" field, used to track internal fragmentation for
  memory statistics purposes, left uninitialized. The problem was that in
  Z_Free, only with INSTRUMENTED defined, the amount of space in the block minus
  the "extra" field is memset with gametic & 0xff to randomize memory (the idea
  being that it will cause a crash when freed memory is accessed, and I've found
  in the past that it's quite reliable at doing that).
  
  This out-of-control memsetting would completely trash the C heap and cause
  some pretty weird looking segmentation violations. I'll note that I was aware
  of the existence of this problem as early as my work doing MBF beta testing; 
  Lee's double boss brain super war level would always crash after it started
  using "virtual" memory. The same went for DOOM II MAP30 in MBF, SMMU, and 
  earlier EE versions.

  I found the problem by accident while doing stress testing with nuts.wad --
  every time the amount of allocated RAM exceeded 16 MB and started using
  system malloc, I'd get a hard crash a few frames later in MSVCRT.DLL that
  always pointed to a Z_Free line. When I printed the zone heap, I noticed that
  several blocks had values like 0x62626262 in their zone ID fields, and then
  the real kicker -- the thinker list was getting corrupted the same way. I 
  knew at that point that I was looking at something related to the memset in
  Z_Free. That led me directly to the vm block allocation code where I noticed
  the missing intialization for block->extra.

  Note that this has only ever affected *debug* builds of Eternity, thus you'll
  never have experienced this crash in any release.

--------------------------------------------------------------------------------
10/02/06

Figured out how to *really* fix general screen patch scaling. I just needed to
add 1 to the inverse scaling factors that are used to step in column space. This
pushes them up just high enough so that they go to the next pixel when they
would if the computer were doing ideal real number math (ie, 3*0.333... should
equal 1 and not 0.99998). This introduces an error of one pixel per every 65536
that are drawn, so at current possible screen resolutions there is no error at
all (I dread the day when 65536 is a possible screen dimension :P ).

Work on floor sequences continues.

--------------------------------------------------------------------------------
09/30/06

Worked REALLY late tonight. Three errors were fixed:

1. A heap corruption problem was being caused by a mistake I made in my tweak to
   have sounds always replace the sound of *lowest* priority instead of the
   first sound they find with a lower priority. This actually reduces loop
   overhead in S_getChannel rather than increasing it, as the search op can be
   done in a loop that was already there, and then a later loop can be 
   eliminated altogether. But I was forgetting to actually set the channel
   number to the number of the channel with the lowest priority when this
   happened, so it was writing to channels[32] and trashing the next block on
   the zone heap.
   
2. While trying to help me fix this, SoM found out that sound link volume wasn't
   being clipped into range and caused an error in i_sound.c due to some out-of-
   date EDFs that still had a volume specified on the chgun sound.
   
3. I found the REAL ultimate reason for sounds playing at the wrong volume.
   There was a race condition between S_UpdateSounds and I_SDLUpdateSound,
   the latter of which DOES appear to be called from a separate thread as I
   have long suspected. If S_UpdateSounds was called before I_SDLUpdateSound
   (or during?), sometimes channels that had stopped were missed and would
   continue to have their hardware channel's parameters modified. This would
   cause any new sound reusing the same hardware channel (started in an
   S_StartSound call between S_UpdateSounds and I_SDLUpdateSound) to be
   modified instead of the original.
   
   I tried a number of different fixes to this but none were satisfactory until
   I thought of giving every sound that's played a unique ID number. ID numbers
   start at 0 and increase by one every time a sound is played. If a software
   and hardware channels' IDs don't match, that software channel won't be
   adjusted or stopped again until it has been cleared out by S_UpdateSounds. 
   This makes the timing of calls to I_SDLUpdateSound irrelevant. This requires
   a new low-level sound API function I_SoundID that returns the idnum for the
   given hardware channel handle.

--------------------------------------------------------------------------------
09/28/06

More work on ceiling sequences. I have also revamped the entire sound engine
priority system, and I believe problems with the old handling of priority were
the source of the weird sound cutoff problems that were plaguing me back in
August.

Basically, the original sound engine ignores sound priority. If an overflow
occurs with respect to the number of channels needed, it cuts off the first 
sound it finds with "lower priority." But the priority values stored in sfxinfo
are not even used! All sounds not played through links were given a default
priority value, so they were all equal. This meant that the very first sound
found playing was generally cut off, even if it was something of relatively far
greater importance.

Say for example that an Imp is scratching your face. But 1500 units away are 32
crusher sectors whirring away at near-zero volume and using up all the sound 
channels with their obnoxious stnmov sound. The crushers may very well override
the Imp, even though if you had a choice on what you'd rather hear, it would be
the Imp and not the crushers.

Now, priority values are loaded into the sound channels themselves, and they are
scaled with the volume of the sound, so that quiet, more distant sounds have
lower priority. As a dramatic example, a Cyberdemon in a large group of Imps
would be sure to have his menacing MOOO! sound heard because his wakeup sound
priority is very high and does not scale down with distance, whereas the Imps'
sound is lower priority and scales down the further away they are. This makes
sense obviously, because if there's a Cyberdemon around, you always want to know
about it.

I had to change the priority values of all Heretic sounds, because the old
values were actually inverted. I took another look at Heretic's sound code, and
it does something very similar to what I've done, except that their priority
scale is inverted relative to DOOM's.

In DOOM, a larger number means lower priority. So a Cyberdemon MOOO is high
priority at 32, whereas an Imp's idle chortling has a paltry 120. This seems
confusing even to me, so I can't blame Raven for changing it. In Heretic, a low
number means low priority. For example, global ambience sounds were given a
priority of 1, which is lower than anything else under their system. This makes
more sense, but for compatibility purposes I have to maintain DOOM's values in
preference to Heretic's.

--------------------------------------------------------------------------------
09/27/06

Began work on sound sequence support for ceiling actions.

--------------------------------------------------------------------------------
09/26/06

Added a tweak to the sound sequence system that will make Hexen work when the
time comes to worry about that. Basically, "door" and "plat" type sequences
need dedicated lookup arrays that store any sequences marked of that type with
numeric ids between 0 and 63. These take precedence over the normal numeric
sndseq hash table.

I added a restart command for sound sequences after noticing zdoom has this,
although it's not very useful yet because I'm not moving the envirosequence
engine into data. I think it works fine as a native system, and I can provide a
special enviromanager block in EDF to allow the user to tweak its default
settings.

Sound sequences now work for plat sectors :)

--------------------------------------------------------------------------------
09/25/06

Added topdamage field for 3D object burning, which was previously implemented as
a special-case hack for FireBrazier objects for testing purposes.

Added Heretic's environmental ambience sequences to sounds.edf, added the 
ability to have pure sound aliases, changed MapInfo environmental sound 
replacement to work with the sound sequence engine, and began integration of 
sector sound sequences, starting with doors.

The difference between sound links and sound aliases is a bit difficult to
explain, but basically it's like this:

A) A sound alias simply provides another name by which the aliased sound can be
   played. It will be played in the exact same manner as though it had been
   started via its own name, because alias resolution is performed first.
   
B) A sound link provides an entire separate set of parameters for playing a
   sound. Links are resolved after all the data has been used to setup the sound
   for playing.
   
Sound aliases are needed so that the default sound sequences can use them and
therefore become gamemode independent to the largest degree possible.

I have also expanded the sound volume precision that is sent down to the system-
specific sound driver code, increasing the range from 0-15 to the full 0-127.
This gets rid of the presentation of false precision in ambience and sound
sequences, and it smoothes out distance attenuation significantly.

--------------------------------------------------------------------------------
09/22/06

Fixed an error in the spechit emulation that was adapted from Chocolate Doom,
and I let fraggle know about it :P

--------------------------------------------------------------------------------
09/21/06

Began addition of spechit overflow emulation, originally from prboom+ and with
some tweaks from Chocolate Doom. This should improve Eternity's standing with the
demo watching crowd a bit once again ;)

--------------------------------------------------------------------------------
09/19/06

I created a real realloc function for the zone heap, which is something I had 
been mulling over mentally for a couple of years now actually. The BOOM version
of Z_Realloc was actually naive and always performed the worst case operation;
that is, allocating a buffer of the new size, copying the old one into it, and
then freeing the old one. Not only is this inefficient in a number of cases, 
but it also requires 2 times the necessary free RAM to be available during a
realloc.

The new Z_Realloc recognizes all possible cases:
1. The block can be expanded in place by absorbing the next free block.
2. The block can be shrunk.
3. The block can be left the same size.
4. The block must be moved.

It seems the largest number of reallocs do fall into category 4, but there's a 
significant chunk that do not, and most of them are the ones occuring during
actual gameplay (libConfuse actually generates an enormous number of realloc
calls during EDF, and this skews any statistics I try to generate using the
zone logging file -- most of them are of type 4).

The secret feature is more or less complete now, and options related to it have
been added to the config file.

I added an MDK cheat console command sort of like the one zdoom has. It fires a
tracer that can instantly kill any monster. This comes really in handy when you
summon up something that you don't really want to deal with ;)

--------------------------------------------------------------------------------
09/18/06

Finished up memory usage improvements by creating a conditionally compiled log
file system for the zone heap which can record all memory operations.

--------------------------------------------------------------------------------
09/13/06

Made small tweaks to some of EE's parameterized codepointer functions.

--------------------------------------------------------------------------------
09/11/06

Low detail mode integration has been completed, along with the addition of the
ability to have multiple span drawing engines as well (now you can use the old
inaccurate drawers if you're an ultra-purist; me, I'll stick with the new ones).

I have begun a massive sweep of the source code to find allocations that are at
PU_STATIC level which should actually be PU_CACHE. The vast majority of these
appear to be patch graphics used in the HUD, menus, and other systems.

--------------------------------------------------------------------------------
09/05/06

In connection to the special feature, I have changed the music volume range back
to its original 0 to 15, I have enabled the ability to have a single unified
mouse sensitivity setting instead of two independent axes (in actuality, setting
the unified value just propagates the value to both of the normal settings), and
I have also added the ability for the game engine to use multiple column drawer
engines. This is in preparation for the restoration of "low detail" mode. I
restored the old column drawers and made the quad cache optimization an option
alongside the original rendering method.

--------------------------------------------------------------------------------
09/01/06

Applied some bug fixes and tweaks to the e_thingtype console command.

--------------------------------------------------------------------------------
08/31/06

Work on the special feature continues, and it's almost complete.

--------------------------------------------------------------------------------
08/30/06

Added an "emulated" flag to the menu system to standardize some behavior
previously hard-coded to the emulated old main menu.

Added memorial messages for Toke, and bumped everything up to the new version.

--------------------------------------------------------------------------------
08/21/06

A truly horrible weekend for the Doom community. Since I'm actually writing this
well after the fact, I won't go into a lot of detail, but suffice it to say that
our friend Toke will be sorely missed. I have already decided to dedicate the
next release of Eternity, which will now be deemed v3.33.50 "Phoenix", to his
memory. I'm also working on a "secret feature" that will be a nice little extra
touch for this release, and something that Toke might have appreciated since he
loved the oldschool purist DOOM.

This kind of tragedy has a way of grabbing you and slapping you hard in the face
over and over until you realize just how fleeting and tenuous life really is.

--------------------------------------------------------------------------------
08/09/06

The whole 3D clipping fiasco put me off coding for a while and so I didn't get
much done during the past month. Amongst things that were done, however, are
basic types for EDF things. These are standard sets of flags that can be
extended in the future without breaking peoples' EDF patches.

I've noted a long-standing problem in the sound engine. Sometimes sounds seem to
be getting cut off unexpectedly. For example, a demon's snort in the E1M5 demo
for Ultimate Doom seems to cut off the player's shotgun blast. Extensive
debugging hasn't revealed anything yet, but I know I'm not just imagining this.

--------------------------------------------------------------------------------
07/04/06

July 4th. How patriotic. Anyways, during the past week I have integrated a
tweaked version of zdoom's 3D object clipping code into Eternity to replace our
defunct system. It seems to work flawlessly after some initial difficulties with
touchy objects and 3DMidTex lines. The new system has some capabilities our old
one did not, including the ability for me to easily add fire damage to things
like torches when you stand on top of them :)

--------------------------------------------------------------------------------
06/26/06

I fixed a bug in EE's screen patch scaling that was making black pixels show up
at the ends of some columns (this was the cause of the dark lines on the R_Init
loading box at startup).

I have also discovered that 3D object clipping is once again completely broken
with respect to sector movement. I have no idea if my recent changes are
responsible for this (and if so, which), or if this is a problem reaching back
to or earlier than the last release. The problems in the system have come to a
head and must be dealt with. I have again made a new experimental fork of the
engine to work with. Right now I'm thinking about trying to restart from 
scratch with it :(

--------------------------------------------------------------------------------
06/20/06

Fixed some bugs in the text HUD widgets.

--------------------------------------------------------------------------------
06/19/06

Yay it's my birthday!

Today's a big day for Eternity too. The release of Crucified Dreams revealed 
some problems in EE's MapInfo system that required addressing so that I could
make a custom MapInfo lump for that project. I also bit the bullet and got the
seg limit expansion done at long last. The entire "ordeal" lasted about 5 
minutes and was incredibly simple. The limit on all mutually referencing map
entities should now be 65535 rather than 32767. Yet more sound sequence work has
also been done.

--------------------------------------------------------------------------------
06/17/06

Got many things done. More joe Small functions and work on sound sequences. I
found a long-hidden bug in the music engine that was doing a case-sensitive
compare on lump names. This was failing to pick up new music lumps. Put in some
tweaks for 3D object clipping to try to make it more symmetric. Fixed a bug in
joe's free TID function related to maxing out the value of an unsigned short and
trying to compare against the value -- an infinite loop could occur. I also made
the 32-bit rendering fixes conditional on the R_SIXTEEN define just in case
there are problems with the changes.

--------------------------------------------------------------------------------
06/10/06

After a few days of work, I have finally cracked the cause of a long-standing
crash bug in the DOOM engine related to areas of height 2500 or greater. The
Caves of Circe level from Hexen was crashing reliably in the same place every
time I fell down a deep hole. By saving the game and jumping off again and
again and employing both printf-style debugging as well as all of the debugger's
tools, I found that the same integer underflow in the clipping arrays could
cause three different errors:

1. The error would be caused by R_DrawColumn attempting to draw to some
   outrageous coordinate such as 32000.
2. The game would crash in R_DrawSpan in a similar manner.
3. The game would trash out almost the entire BSS static variable memory segment
   via an out-of-control iteration on the spanstart array in R_MakeSpans, and 
   then segv at some  arbitrary point later, often during shutdown when trying
   to write the configuration file. This made debugging more complicated, but 
   once again my invaluable experience with the "two-week bug" enabled me to
   instantly recognize the overflow when it happened. Determining where it 
   happened was a bit more difficult, since map files generated by VC++ 
   obviously do not include static variables. I had to insert guard variables
   around the various arrays in the renderer to check for the overflow's
   beginning in RAM.

The problem? Short ints aren't sufficient for the clipping arrays in DOOM. If
the difference between floor and ceiling is too large in the right circumstance,
it will attempt to store a value into the array that is less than -32768. This
causes integer underflow, resulting in a value of +32000 typically. Since
there's by necessity no bounds checking (and I'll note my attempts to add it
ended in frustration), the error goes uncaught and makes the game go crazy
later when trying to draw the underflowed columns or spans.

The solution? Upgrade all clipping arrays, including openings and spanstart,
to 32-bit integers. This doubles the amount of memory usage, particularly for
visplanes, and will hurt cache performance, no doubt. However, the framerate of
the engine doesn't seem affected on modern machines so my concern is minimal at
this point.

Also added some of joe's new Small natives :)

--------------------------------------------------------------------------------
06/06/06

The sound sequence engine is largely complete, including support for Heretic's
global environmental ambience sequences.

--------------------------------------------------------------------------------
06/04/06

Added s_sndseq.c module and did major sound sequence work. I also got rid of
the old Linux and MinGW build scripts that were obsolete and/or broken.

--------------------------------------------------------------------------------
06/03/06

Began laying ground work for sound sequences.

--------------------------------------------------------------------------------
06/01/06

You can now run console scripts from the command line using -exec. I added this
mainly because 3.33.35 will require a console script to be run the first time to
restore default values to the new dynamic console keybindings. Otherwise,
everyone's keys.csc would be out of date again, and that was a nightmare last
time. Removed pretty much everything DOOM-specific from eterhtic.wad to make it
half the size it was before.

--------------------------------------------------------------------------------
05/31/06

Made EDF significantly more error-tolerant by substituting default values for
some bad entries, sounds in particular. Warnings are now issued to the verbose
log instead of causing an exit. Began work on EDF ambient sound definitions,
inspired by Mordeth and some stuff I saw in zdoom's documentation.

Added joe's new Linux build system to replace the ancient, no longer working one
that fraggle made many years ago. Joe intends to build the Linux releases for me
in the future, as well as making SVN revision compilations on an irregular
basis.

--------------------------------------------------------------------------------
05/26/06

Partially generalized the finale system so that you can specify what type of
finale sequence occurs after a map via MapInfo :)  I needed this for my new
"Episode 5" project, which needs a just-text intermission after the first map,
but in Ultimate DOOM which didn't previously support text-only intermissions
that go to the next map (they always ended the episode).

--------------------------------------------------------------------------------
05/25/06

Started research for the impending rewrite of the console. Quake 2's source code
is going to be enormously useful, for I have found that it has a significantly
cleaner and more efficient method of storing console text than any I had even
imagined (I wish I had thought of it on my own...). I added a routine to the
font engine that goes through all the patches of the font and finds the widest
character width. This will be needed to more accurately calculate the number of
characters allowed per console line.

I've also made some minor adjustments to help joe_ compile under Linux.

--------------------------------------------------------------------------------
05/22/06

Added a new ALWAYSFAST flag, which makes a monster always have -fast/Nightmare
attack speed behavior. Note that this doesn't speed up any fireballs they shoot,
however, since that is handled separately through the fastspeed, nor would it
make the Demon's walking frames half duration.

--------------------------------------------------------------------------------
05/21/06

Consolidated the gameinfo_t structures for Shareware, Retail, and Ultimate DOOM
since only two whole fields differed between them. Those fields are now patched
at runtime in d_main.c. I didn't delete the extra structs from the source,
however, since it might be necessary to go back to the older setup if more
fields are introduced that differ from the Retail settings.

I also made a ton of minor adjustments that allow the port to be built with the
Dev-C++ MinGW-based development package. The worst bug I got rid of was that the
packing attributes on structures in amx.h (the Small compiler) were being
totally ignored due to interference of typedefs. I should probably change my
project to use -Wall and kill off some warnings too.

I also got the DOS build running again. Why? I dunno, nostalgia maybe? I plan to
do a full multiplatform release for the next version so that Eternity can 
definitively claim to be the last port to support DOS. The worst changes that 
DOS needed were 1) I forgot to change ENDOOM loading to be gamemode-dependent in
the DOS version of the code, and 2) there's no STDISK crap in Heretic, so that 
also has to be switched off via gameModeInfo. This was technically a bug in the 
SDL version too, except that disk drawing is currently broken and therefore de 
facto disabled there.

--------------------------------------------------------------------------------
05/19/06

Figured out why flat swirling was crashing. SoM was accidentally accessing
flattranslation[pl->picnum] and using its value when it was equal to -1 as an 
addend with firstflat in the argument to W_CacheLumpNum. Fixed by restoring
pl->picnum to flattranslation[pl->picnum] after determining whether or not the
flat is swirling (swirling flats don't animate, so this works fine).

I also found out that my portal tainting system wasn't quite complete. Only the
first generation of child portals were properly reset, and portals were still
starting out with an uninitialized taint value at the beginning of the level,
which would cause spurious rendering failures the first time you laid eyes on
them (dunno how I missed this).

--------------------------------------------------------------------------------
05/18/06

Numerous issues have been found by different people in 3.33.33, so a maintenance
release will most likely be forthcoming in the near future. Work has already
begun, actually.

I found an easy way to vastly optimize the blockmap unlinking operation for
PolyObjects. During linking, the polymaplink_t's generated are now stored on an
additional single-linked list that originates in the PolyObject itself. This way
when the object is unlinked, I can simply run down this single-linked list and
delete each node instead of searching the blockmap for the links. It's so simple
that I'm plain sick that I didn't think of it earlier :P

================================================================================
EOF
================================================================================