It is utterly pointless to require every function that wants to make a VM call to allocate a new stack first. The allocation overhead doubles the time to set up the call.
With one stack, previously allocated memory can be reused. The only important thing is, if this ever gets used in a multithreaded environment to have the stack being declared as thread_local, although for ZDoom this is of no consequence.
- eliminated all cases where native code was calling other native code through the VM interface. After scriptifying the game code, only 5 places were left which were quickly eliminated. This was mostly to ensure that the native VM function parameters do not need to be propagated further than absolutely necessary.
It's about time this stuff is getting cleaned up seriously. Both a_pickups.cpp and a_artifacts.cpp are so overstuffed that it has become a chore finding stuff in there.
- Changed the glass shards so that they do not have to override FloorBounceMissile. It was the only place where this was virtually overridden and provided little usefulness.
- made 'out' variables work.
- fixed virtual call handling for HandlePickup.
Needless to say, this is simply too volatile and would require constant active maintenance, not to mention a huge amount of work up front to get going.
It also hid a nasty problem with the Destroy method. Due to the way the garbage collector works, Destroy cannot be exposed to scripts as-is. It may be called from scripts but it may not be overridden from scripts because the garbage collector can call this function after all data needed for calling a scripted override has already been destroyed because if that data is also being collected there is no guarantee that proper order of destruction is observed. So for now Destroy is just a normal native method to scripted classes
This bypasses a declaration in the script in favor of a simpler implementation. In order to work it is always necessary to have an offset table to map the variables to, but doing it fully on the native side only requires adding the type to the declaration.
Daedalus triggers this with a 0x85 character which in Windows CP 1252 is the ellipsis (...) The converter will assume ISO-8859-1, though, but cannot do anything with these characters because they map to the font being used here.
This was probably responsible for some weird behavior recently, but with the addition of the OF_Transient flag this outright crashed because it left NULL pointers on reload in places where they weren't checked for.
* everything related to scripting is now placed in a subdirectory 'scripting', which itself is separated into DECORATE, ZSCRIPT, the VM and code generation.
* a few items have been moved to different headers so that the DECORATE parser definitions can mostly be kept local. The only exception at the moment is the flags interface on which 3 source files depend.
After testing with a savegame on ZDCMP2 which is probably the largest map in existence, timing both methods resulted in a speed difference of less than 40 ms (70 vs 110 ms for reading all sectory, linedefs, sidedefs and objects).
This compares to an overall restoration time, including reloading the level, precaching all textures and setting everything up, of approx. 1.2 s, meaning an increase of 3% of the entire reloading time.
That's simply not worth all the negative side effects that may happen with a method that highly depends on proper code construction.
On the other hand, using random access means that a savegame version change is only needed now when the semantics of a field change, but not if some get added or deleted.
- do not I_Error out in the serializer unless caused by a programming error.
It is better to let the serializer finish, collect all the errors and I_Error out when the game is known to be in a stable enough state to allow unwinding.
It turned out this may not be done automatically when opening the savegame - it has to be done later, after the pre-spawned map thinkers and all connected objects have been destroyed.
The object deserializer also has to be rather careful about dealing with parse errors, because if something goes wrong a whole batch of uninitialized or partially initialized objects will be left behind to destroy.
This means that no object class may assume that anything but the default constructor has been run on it and needs to check any variable it may reference.
- fixed a few errors in the ACS module serializer.
- reordered a few things to how they were in the old code.
- optimized serialization of the level.Scrolls array to happen within the sector. This is to allow skipping 0-entries which normally constitute the vast majority of them.
The way this was done was a major headache inducer, requiring reconstruction of the function each time the value was changed and in general made actor damage a major hassle.
There was a DECORATE wrapper to mimic the original behavior but this looked quite broken because it completely ignored the different semantics of both damage calculation types.
It also made it impossible to determine if damage was a function or a value.
This accessor has been reverted to what it should be, only returning the constant, which now is -1 for a damage function. I am sorry if this may break the odd mod out but a quick look over some DECORATE-heavy stuff showed that this was never combined in any of them so that accessing 'damage' in DECORATE code depended on an actual damage function.
To get proper damage, a future commit will add a DECORATE function which calls AActor::GetMissileDamage.
int SetActorFlag(int tid, str flagname, bool value);
- Mimics DECORATE's A_ChangeFlag
- Returns number of actors affected (number of things with the flag)
- Affects activator if TID is 0
# Conflicts:
# src/p_acs.cpp
It acts as a simple wrapper around P_DamageMobj which can damage a
single actor, but can also set the actor inflicting the damage. It
returns the amount of damage actually done, or -1 if the damaging was
cancelled.
bool CheckActorState(int tid, str statename, bool exact = false);
- Same parameter order as SetActorState
- Returns true if actor has the state; else returns false