TurnActorTo is mapped to Actor::singleTurnTo() which only
turns the actor (according to its turn rate) by a small amount.
If the turn could not be completed, TurnActorTo returns false.
In EMI, all LUA calls to TurnActorTo are repeated until the
actor does eventually look into the correct direction.
However, for parallel running LUA threads, calls to IsActorTurning
would return false during such a "LUA-controlled" turn.
In the scene with the dart players, the LUA code for the dialog
waits for the dart player to stop moving (and turning) by repeatedly
calling IsActorTurning. Since that function returns false
even if the players are still turning towards the dart board, the
dialog code starts and spawns a parallel LUA thread to use
TurnActorTo to make the dart players looking at Guybrush.
This means, that eventually for each dart player, two LUA
threads with contradicting TurnActorTo directions will run forever
since in none of the threads the final direction is ever reached.
To fix that, a new actor state variable, _singleTurning, is introduced.
It is set to true if an Actor::singleTurnTo() call indicates that
the turn is not complete. It is set to false once the turning has
fininshed.
Since all TurnActorTo calls in EMI are repeated until the function returns
false, it is safe to use that variable to indicate that a "LUA-controlled"
turning is in progress.
In GRIM, that's not the case and so isTurning() is only changed for EMI.
Mesh is the only component that actually usees _matrix, and it
has it's own local _matrix variable. This remove the confusion over
which _matrix variable is actually used and removes saving _matrix
for all the components that don't use it.
Sometimes a texi component may refer to a material that was initialized by some other costume than the owner costume of the texi component. For example, the candles in gmi have a costume "fx/aura1.cos" that controls the animation of a material originally initialized by a sprite component of "fx/candle.cos".
Lighting is done by calculating vertex colors in software, since the attenuation model used in EMI cannot be simulated with OpenGL fixed function lighting. The original game does the lighting this way as well. Ideally for the modern shader-based renderer a shader would be used for this instead.
Previously chore instance IDs stored as Lua userdata became invalid after
loading a save, because the chores were recreated with different IDs. This
caused certain opcodes like StopChore to fail.
The clean buffer code needs two layers. Every actor needs its buffer,
but we also need a global one. The actors' buffers blit to the global buffer
which then gets blitted to screen.