This appears to be the only case where an actor was set to a state owned by a completely unrelated actor which would present some problems with state owner checking in AActor::SetState, so let's better get rid of it ASAP.
I believe the only reason this wasn't changed when all actors were exported 8 years ago was that old binary DEHSUPP lump.
This could cause problems with functions that take states as parameters but use them to set them internally instead of passing them through the A_Jump interface back to the caller, like A_Chase or A_LookEx.
This required some quite significant refactoring because the entire state resolution logic had been baked into the compiler which turned out to be a major maintenance problem.
Fixed this by adding a new builtin type 'statelabel'. This is an opaque identifier representing a state, with the actual data either directly encoded into the number for single label state or an index into a state information table.
The state resolution is now the task of the called function as it should always have remained. Note, that this required giving back the 'action' qualifier to most state jumping functions.
- refactored most A_Jump checkers to a two stage setup with a pure checker that returns a boolean and a scripted A_Jump wrapper, for some simpler checks the checker function was entirely omitted and calculated inline in the A_Jump function. It is strongly recommended to use the boolean checkers unless using an inline function invocation in a state as they lead to vastly clearer code and offer more flexibility.
- let Min() and Max() use the OP_MIN and OP_MAX opcodes. Although these were present, these function were implemented using some grossly inefficient branching tests.
- the DECORATE 'state' cast kludge will now actually call ResolveState because a state label is not a state and needs conversion.
Now even in DECORATE it is possible to report most cases in which user variables are accessed from non-item states as an error. This will report all states which can be traced by a direct link from a special state label. It will not find states that only get used via A_Jump etc.
- since we now look for fields in the base class first the restriction check is no longer needed as it was for a different mode of looking up the identifier.
- In DECORATE we do not need to bother with non-action functions. Non-action functions cannot be defined from DECORATE so there's no need to check if we are in one.
- make the warning for unsafe access a debug message because this can affect legitimate code.
- Replaced GTK/OS X (note different from Cocoa) clipboard code with SDL clipboard API.
- Removed requirement to link to GTK in order to compile with GTK support.
- GTK is no longer init'd if the GTK IWAD picker is not used.
- Our usage of GTK is such that the dynamic loader can work with both GTK2 and GTK3 depending on what's installed.
- Since we're accumulating a lot of library loaders I've built a generic interface as FModule which replaces TOptWin32Proc and the loaders in the OpenAL and Fluidsynth code.
- fixed creation of direct function invocations on a state line. In order to receive the implicit arguments this needs to be wrapped into a compound statement so that the local variable getter works.
The proper setup for such classes was only done in CreateDerivedClass, but not in FindClassTentative itself. This extends CreateDerivedClass to allow it to create a class without fully initializing it.
- removed AMinotaurFriend::IsOkayToAttack. The condition it checks (i.e. friendliness with player) is already covered by the base version of this function so this is quite redundant.
- removed a few 'virtual' qualifiers from functions that never get overridden.
- If con_numnotify < 0, then there is no limit on the number of lines of
text.
- If con_numnotify == 0, then any text that would normally be shown in the
notification area is discarded.
- If con_numnotify > 0, then that is the maximum number of lines of
notification text to display.
Syntax-wise I chose to make it as strict as possible to reduce the chance of errors: Virtual base functions must be declared with the 'virtual' keyword, and overrides in child classes with the 'override' keyword. This way any mismatch in parameters that otherwise would cause silent failure will outright produce a compile error.
- made 'DamageMultiply' an actor property and moved the initialization of ConversationRoot to the property handler for the compiler to get this stuff out of the type classes.
- consolidate default initialization into one function which performs all the required setup. The original implementation did this when adding the fields but that cannot work because at that time no defaults have been created yet.
- fixed: When deriving a class the child class's defaults also must initialize the copied parent fields with special initialization. This part was completely missing.
- removed DECORATE code for parsing native classes because it's no longer needed.
- Since the number of small allocations here is extremely high this will help a lot to prevent fragmentation and since most nodes are collected up front and this is done when no large resources are being loaded it won't cause heap spikes.
let Emit methods delete FxExpression arrays when they are done.
- For some reason the deletion process does not work 100%, there are always some nodes left behind and so far I haven't found them. This ensures that these arrays do not live any longer than needed.
- fixed: The state cast hack for DECORATE could not properly create state constants.
Instead they were passed to FxRuntimeStateIndex without resolving them to something constant. This adds proper handling of constant indices within that class.
* use the function build list instead of the function to pass the info. The function is permanent so not the best place for compile-time info.
* pass along the current state index which is needed to calculate the target state.
- made some tests about calling script code from native functions.
* scriptified A_SkullAttack to have something to test
* changed the A_SkullAttack call in A_PainShootSkull.
* use a macro to declare the function pointer. Using local static variable init directly results in hideous code for the need of being thread-safe (which, even if the engine was made multithreaded is not needed here.)
* Importsnt node here: Apparently passing an actor pointer to the VMValue constructor results in the void * version being called, not the DObject * version.
- Polygons will be clipped to bottomclip. If this is zero or below, they
will be clipped to the bottom of the screen instead. This keeps the
polygons from overwriting the status bar border for sofware 2D. The
hardware version ignores it, since it always draws the status bar border
every frame.
- fixed: The state index comparison against 0 was broken.
- fixed: Resolving codegen nodes must set the strictness flag per function so that ZSCRIPT and DECORATE are done properly.
- added an 'exact' parameter to FThinkerIterator's Next function. This is mainly for scripting which allows to do a lot more checks natively when running the iterator while looking for one specific class.
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.
- fixed: divisions wasted one register for each operation due to a double allocation.
- changed math operations to use less registers. There was a well-intended change to allocate the destination first, but the better approach is to first allocate the operands and free then before allocating the destination register.
- added support for global variables to the code generator - not the compiler, though. For the handful of entries this is needed for it may just as well be done manually. So far FLevelLocals level is the only one being exported.
- fixed: The VM disassembler truncated 64 bit pointers to 15 digits because the output buffer was too small.
- resolve entire FxSequences instead of aborting on the first failed entry. This allows to output all errors at once.
* Revert "Modify CMPJMP to produce more compact code (as far as VC++ is concerned, anyway)"
This reverts commit 6ff973a06b.
This modification did not work and broke the comparisons. Actually this had three problems:
* the asserts checked the wrong instruction
* the mask was not applied to regular comparisons.
* incrementing PC before testing does not work because 'test' references the PC.
* Revert "Modify CMPJMP to produce more compact code (as far as VC++ is concerned, anyway)"
This reverts commit 6ff973a06b.
This modification did not work and broke the comparisons. Actually this had three problems:
* the asserts checked the wrong instruction
* the mask was not applied to regular comparisons.
* incrementing PC before testing does not work because 'test' references the PC.
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.
- These require manual detection and overriding of the scaling factors to
0, because a right shift of (32-0) bits wraps around to 0 and results in
no shift at all rather than leaving the register zeroed out.
- dc_destorg is normally set to the upper-left corner of the view window.
If there is a border, then this won't coincide with the upper-left
corner of the screen, and DCanvas::FillSimplePoly would merrily write off
the end of the screen buffer.
- exported thinker iterator and drop item chain to scripting. Unlike its native counterpart the script-side iterator is wrapped into a DObject to allow proper handling for memory management.
- fixed: The VMFunctionBuilder only distinguished between member and action functions but failed on static ones.
- fixed: FxAssign did not add all needed type casts. Except for purely numeric types it will now wrap the expression in an FxTypeCast. Numeric handling remains unchanged for both performance reasons and not altering semantics for DECORATE.
- exported all internal flags as variables to scripting. They still cannot be used in an actor definition.
- make ATAG_STATE the same as ATAG_GENERIC. Since state pointers exist as actual variables they can take both values which on occasion can trigger some asserts.
- gave PClass a bExported flag, so that scripts cannot see purely internal classes. Especially the types like PInt can cause problems.
Todo: we need readonly references to safely expose the actor defaults. Right now some badly behaving code could overwrite them.