It serializes objects using a selective SaveScenarioObjects script callback and then just executes the generated script. This automatically saves important properties, connects switches and doors, etc.
This change also solves the problem that duplicating an elevator plus case would create two elevator cases.
If execution fails (e.g. because of script errors or because a non-saveable object was duplicated), the method falls back to the legacy duplication method of creating objects with the same prototypes at the same position.
C4Group::SearchNextEntry would waste lots of cycles looking up file
attributes that were never inspected afterwards. Since all we want is
the file size, and we already get that for free from FindFirstFile and
FindNextFile, store it with the directory iterator instead of querying
it at every iteration.
This reduces load times on my machine by almost half, tested across
several different scenarios.
Our hardware-based skinning doesn't work on certain Intel graphics
devices. Fall back to software skinning on GPUs that return an OpenGL
3.1 context even though we explicitly request a 3.2 one.
Might fix#1459, #1689.
- The new code works with my router while libupnp didn't. :)
- There are some unexplainable crashes in libupnp: #1640
- Using miniupnpc seems to be less complex than libupnp.
- Apparently, miniupnpc also works on Windows, so we may be able to use
it for all platforms.
Disadvantage: UPnP queries aren't asynchronous anymore, but they seem to
be pretty fast (< 1 s).
It could happen that the objects were cleared (after evaluation screen / on section change) but a particle list would remain that would still point to an object (and would then access it).
I am not exactly sure how that could happen, because objects should clear their particle lists on removal (and thus shouldn't really need a ClearPointers).
There is a tiny chance that this points to another bug somewhere in the object removal - that's just a random guess though.
Anyway, this should fix the infamous Knüppeln crash.
Declaring a local variable inside any function works the same way as
declaring it in top-level scope, which gets a bit weird if done inside a
function inside a constant proplist, but is at least consistent.
Thanks to Flinti for reporting this.
On High-DPI displays, the mouse cursor is very tiny. We'll probably want
some high-resolution cursor graphics at some point, but the current ones
scale good enough.
All the other effect callbacks silently ignored missing functions, either
by using the Call variant that doesn't complain about it, or checking for
the missing function themselves.
Effects with prototypes were supposed to inherit their names from the
prototype, but the effect prototypes are also supposed to get their names
from ParentKeyName, which is not inherited. Maybe that'll change, but for
now this matches how old effects work.
Apparently this is recommended so that a std::vector actually uses the
move constructor. In any case, the second parameter wasn't used, so this is
a nice simplification as well.
Employ variadic template arguments and more rvalue references for this.
Sadly, StdParameterAdapt itself is even more complicated, since it has to
store the parameters instead of just forwarding them, so the limit is still
two parameters. But that's twice as much as before in many cases.
Thanks to ck, who noticed. Apparently it got lost when reverting some changes back and forth for testing, because I had one revision where I didn't need it anymore but I reverted most of that.
Some particles were visibly missing. The reason was apparently that the VAO was initialized with an IBO that was yet too small (because not all particles were created yet).
To be honest, I don't know why the IBO needs to be rebound as the identifier itself does not change(?) but maybe OpenGL optimizes some stuff and needs the size fixed?
Steps to reproduce: In OneMillionParticles.ocs, make Test3 be the first test (otherwise the IBO would have been large enough). You would now not see all of the fireworks.
The issue was introduced in e13cda4bd0
Otherwise the IBO is created from scratch for every particle that is e.g. created in a for loop. This is extremely slow and unnecessary.
The symptoms was that OneMillionParticles appeared to 'freeze' on the non-batch creation test. (Hint: it didn't freeze, it just took forever).
The C++ standard says that it doesn't matter whether you forward declare
something as struct or class and then define it using the other keyword.
Unfortunately MSVC adds those keywords to its name mangling scheme,
which breaks things.