The function to do the work scanned the full list of drawsegs to find portals, which with a large amount of masked geometry and/or drawsegs could become extremely slow.
Changed it so that R_DrawMasked collects all portal related drawsegs up front so that the actual clipping code can
a) scan a far shorter list and
b) can skip half of the validation.
Also using P_PointOnLinePrecise to shave off a small bit of additional time.
The reason is that in such a case it is very likely that the IWAD defines its own menu and will most likely not provide all assets for the base definitions. See 'Adventures of Square' for an example.
Attempts to output errors with bad characters encountered during text lumps parsing were failed miserably because of UTF-8 conversion
Example: loading of GZ-Models-r16.pk3 with GZDoom caused 'NSConcreteAttributedString initWithString:: nil value' exception
During loading of .pk3 that stores hundred of .wad's significant amount of time were spent on scrolling text to the last line
The same applies to other cases like output of thousands warnings/errors
* Arch-Vile resurrection
* Boom point pushers (due to complete lack of z-handling only for line portals.)
* A_RadiusGive
These also require a more thorough collection of portal groups than simple position checks.
It can easily happen that the lower sector has no lines below the checked area, in which case it would not set the dropoffz correctly. To prevent this, P_LineOpening must, when it checks the opening over a sector portal, actually calculate the dropoff to the lower portal itself by calling sector_t::NextLowestPointAt. It also means that FindRefPoint must calculate a proper reference point when one side of the line to be checked is part of a floor portal.
This fixes Clang complaining about unknown command option '-Wno-unused-but-set-variable' when compiling dumb.
Also I got no new warnings on Clang by excluding '-Wno-unused-result'.
This includes:
* allow one sided portal linedefs to be crossable when part of a polyobject. Due to the limitations, two-sided linedefs won't work here. For general use this is still not allowed because making them passable would require some crippling fudging.
* delay portal finalization until after polyobjects have been spawned.
* the camera interpolation also needs to handle angle differences.
The code is still not 100% complete - the most important thing that is still missing is proper handling of P_CheckPosition through arbitrary portals.
- added portal offsetting to all AproxDistance, AngleTo and Vec*To members of AActor.
- optimized displacement retrieval so that the most common case with no offset retrieves a constant null-vector which can be optimized away fully by the compiler.
- early out in P_GetOffsetPosition if there's no portal lines nearby, so that the common case can skip the traverser completely even on maps with line portals.
- made some minor changes to FPathTraverse so that the Add*Intercepts methods can be virtually overridden.
- removed the PortalTracer class because in its existing form it was too costly. Replaced with a P_GetOffsetPosition function that does the minimum required work to get to the translated destination and that's better suited for being called from the Vec*Offset methods. Other use cases will require some changes to FPathTraverse anyway, or some wrapping class like the FMultiBlock iterators.
- renamed sector_t::soundorg in centerspot, changed the type to a fixedvec2 and removed the CenterSpot #define.
Since this thing was used in lots of places that have nothing to do with sound the name made no sense. Having it as a fixed_t array also made it clumsy to use and the CenterSpot #define used a potentially dangerous type cast.
- Split specific parsing for each intrinsic out of ParseExpression0 and
into their own functions.
- Instead of reserving keywords for intrinsics, identify them by name
within TK_Identifier's handling.
* Blocking lines above or below the current sector should only block if they actually intersect with the currently checking actor.
* Sectors above a ceiling portal should not change current floor information and vice versa.
- Don't use isMissile(). Check directly for the flag at the moment of calling and not the default. Otherwise, things changing themselves will still be ineligible for non-missile checks.
* removed all code for dealing with z-displacing portals in the iterator loops. This would cause too many problems so I decided to scrap any provisions for allowing interactive portals with z-displacement. They will remain restricted to pure teleporter portals.
* changed spechit to carry a position along with the special line. If something is activated through an interactive portal this is needed to calculate movement.
* pass the abovementioned position to CheckForPushSpecial.
* collect touched portal lines in a second array analogous to spechit.
* use FMultiBlockThingsIterator in P_TestMobjZ.
(This is just a safety commit before doing some more extensive behind-the-scenes refactoring.)
Notable changes here:
* use the same logic for determining whether a 3D floor is 'below' or 'above' the actor as all the other functions.
* removed the broken code which tried to detect whether an actor was touching a steep slope. Better use P_LineOpening to find the correct planes and store the results.
* improved detection whether the slopes on both sides of a plane are identical, using the same data as for steep slope detection.
- This is an effort to emphasize that these are just type casts. Now they
look like function-style casts with no action function styling.
They do no magic joojoo at all. The only reason they exist is because
the DECORATE parser can only parse return statements that call a
function, so these satisfy that requirement. i.e. *return int(666);* is
identical to *return 666;* (if the parser could handle the latter).
- Now that state jumps are handled by returning a state, we still need a
way for them to jump to a NULL state. If the parameter processed by this
macro turns out to be NULL, Actor's 'Null' state will be substituted
instead, since that's something that can be jumped to.
This gets lost when several portals are drawn sequentially and this is the only portal type which needs this information but doesn't go through the normal setup.
If this is not done, fog on the horizon plane can break.
Note: This replaces AActor::intersects with a direct calculation. Although that function could be adjusted it'd mean some redundant distance calculations which are easily avoided.