If the play state for the score stops for whatever reason, Lingo will
attempt to bail early so the movie can switch over. Freeze the state so
that we can pick up execution where we left off.
Fixes the location/time announcements in DEVO Presents: Adventures of
the Smart Patrol.
Previously, the Lingo state would be frozen by persisting the frames on
the bottom of the callstack with a special flag. This required extra
logic to determine whether or not the callstack was intended to be empty
after execution finished, with some complex edge cases.
The new approach is to swap out the LingoState object on the window,
meaning that an empty callstack always signifies execution has completed.
It remains to be seen if we'll need to track more than one frozen
context; for now it seems to be okay.
Fixes driving to locations in DEVO Presents: Adventures of the Smart Patrol.
The previous arrangement was to copy the bits of Lingo state back and forth from
the Window object to the Lingo instance, and query the window for the
callstack. This refactor consolidates the current Lingo state into a single
struct, owned by the Window object and accessible via a pointer on the
Lingo object.
When an error happens during go, for example with a nonexisting movie
the lingo callstack isn't cleaned up properly.
Now the callstack is cleaned up via `popContext(aborting=true)`.
This improves on commit:
DIRECTOR: fix memleak when lingo context is frozen
27b314cb25
The Lingo tests were failing because of memory leaks.
- `move` overwrote an existing cast without deleting it
- `puppetTransition` was set but not removed on class destruction
- the *.lingo test files were opened but never removed
Create a variable on ScriptContext to track if it's only in
lctxContexts to ease deletion.
Factories and scripts with script id < 0 are tracked and deleted on
~LingoArchive. The hashmaps lctxContexts and scriptContexts overlap in
the values. The forementioned factories and scripts with script id < 0
were only in lctxContext.
scriptContexts was already cleaned up in ~LingoArchive.
`--debugflags=lingostrict` drops into the debugger when hitting a Lingo error.
When encountering a lingo error the current lingo script execution will
stop but the engine continues as much as possible. This is great when
trying to run a game in the best possible way. It's not so great when
debugging issues, since it leaves the game in an unknown state.
The `lingostrict` option makes it clear where a lingo error occurs.
preLoadEventAbort is a boolean property. When true pressing keys or clicking the
mouse can or stop preloading of cast member. ScummVM doesn't preload, so
implemented as a no-op.
When comparing an Object, i.e. FileIO instance, to an INT or STRING, the
Object is parsed as string and then compared. An Object's string is
<Object:hexcode>, e.g. <Object:794b8d0>. When compared to an INT, it's a
regular string compare.
This make saving and loading work again in Majestic.
Note: '#' < '0' due to ord '#' is 35 and ord '0' is 48.
Implemented changes:
- compare Object as STRING when it's an Object with INT or STRING
comparison,
- set Objects string to start with <Object,
- include lingo test and
- remove BUILDBOT notification on invalid comparion.
With INT and STRING comparisons:
- when the STRING can be parsed as an INT then it's an INT comparison,
otherwise
- the INT is parsed as STRING and it's an STRING comparison.
updateMovieEnabled is a boolean. It's a flag to signal that the changes
in the movie need to be saved when branching to another movie.
The variable is implemented but without any side effect.
The traceLoad property can be 0, 1, 2 or 3. It specifies how much
verbosity is shown when loading cast members.
It's a bt useless for ScummVM. We have our own verbosity mechanism.
Furthermore ScummVM loads all casts up front and unload is a no op.
The actorList is a global array property. Birthed scripts can be added
to it. The `stepFrame` method is called on all objects in the array on
every frame. < D4 had an executePerFrameHook for this.
In Director the exitLock prevents quitting the program when it's set to
TRUE. get and set for the exitLock is implemented.
The underlying functionality, preventing exiting a program, is not
implemented. ScummVM should always respond to a QUIT event.
the searchPath is an array that contains paths that need to be searched
when opening a file. It's a property on the same global level in the
same way itemDelimeter is.
The searchPath is set via cb_theassign2. It's used for assigning
properties to the movie itself. `g_lingo` in the case of ScummVM.
The only known case for cb_theassign2 is in the game Louis Catorze
where it's only used for the searchPath.
Note: cb_theassign() does the same thing for script and factories