Script::_locker is supposed to track the number of classes and objects
that use a script in order to determine when it can be safely unloaded.
But for system script 999, _locker rapidly increases throughout the game
and eventually overflows. This causes script 999 to unload and crash.
Other scripts may also be affected.
We have been provided QFG1 SCI0 saves where this occurred over the
course of hours within only three days. Logging shows this value
skyrocketing in many games even when they are just polling input or
animating the screen. Alarmingly, this suggests that many SCI games
become unplayable in ScummVM after an achievable amount of game time.
This may be a large and complex problem within the script locker system.
For now, we can mitigate this by making Script::_locker unsigned, which
its callers expected it to be, and by logging overflow attempts and
lowering the locker. This fixes existing save games, even if they have
already overflowed the signed maximum.
Somehow, up until trying to view an encrypted data cube in RAMA,
the missing relocation of locals did not seem to cause any trouble
in any of the other SCI3 games.
When a game deletes a script and then loads the same script again
before it has been fully deallocated,
SegManager::instantiateScript tries to reuse the same script
& locals segments, but it was failing to reuse the old locals
segment because Script::freeScript would unconditionally clear
the old locals SegmentId, which meant the old locals segment would
just leak.
This patch does not fix old save games which may contain orphaned
locals segments, but should prevent the problem from occurring
going forward. (It is possible to clean up these old save games,
but this is not a big leak so it doesn't seem worth the extra
effort to do so.)
This groundwork enables an object to look up its static name
separately from the normal process that is used to populate
Object::_variables when an object is first constructed.
(The static name property needs to be able to be retrieved from
objects inside of earlier save games whose name properties may
have already been modified at runtime, so the code cannot simply
pluck the value out of Object::_variables when they are first
initialised and then persisted into the save game, as nice and
easy as that would have been.)
This commit also helps to clarify the situation with relocation
tables in SCI1 games that start with a zero entry.
Refs Trac#9780.
Script buffer data is modified after a script is loaded by
savegame operations, and, in SCI16, by string operations. Casting
away const to allow these mutations to happen is not a very good
design, so this patch just changes the privately held reference
to data to be mutable. (Public accessors still return immutable
data.)
Export functions may be relocated above 64k in SCI3, but exports
that do not have an entry in the relocation table must be handled
the same as SCI1.1-2.1.
The previous fix for this bug was incorrect; it only happened
to work because of another bug: the number of exports was being
read incorrectly (reading the byte size of the export block, not
the number of exports), so the validation check for the export
number always passed. Then, the "small" offsets that were seen
were actually either invalid reads into the header of the next
block in the script (KQ4), or reads into the bad first export
table which contained an unfilled offset (Camelot).
Once the incorrect number of exports was fixed, the previous "fix"
broke in KQ4 because the export number validation started to work
correctly and the first export table does not have enough entries
(needs 2, has 1).
This patch fixes the bug by using the last export table in SCI0
scripts instead of the first export table. (This does not affect
most scripts, since only the buggy scripts have more than one
export table.)
Fixes Trac#9731.
1. pushi opcode now displays decimal value and selector value (if
one exists) in-line
2. lofsa, lofss, and super opcodes now display resolved
object/class names
3. Opcode arguments are visually aligned
Exports with a zero offset are supposed to point to the start of
the code block in the script hunk, but they were being ignored.
This may also apply to SCI1.1 games, but until that can be
verified, this fixes the zero-offset in only SCI32 games for now.
implement string collecting for SCI3
implement object offset collecting for SCI0-SCI2
implement said-str offset collecting for SCI0-SCI1
add new debug command scro / script_objects
add new debug command script_said
string without terminating NUL now a warning
the latter happens in qfg2 for amiga room 84
This is needed for future support of large SCI3 scripts. The program
counter is isolated and does not interfere with other parts of the VM,
plus it does not get stored in saved games, so it's pretty straightforward
to convert
This could happen because objects in scripts can be in the wrong order.
Same thing happens in the French and German version of KQ5 (bug #3035396).
Removed the scriptObjRemove() method, which is in fact a hack.
svn-id: r54510
- Added a SCI3 implementation of Script::load()
- Added a SCI3 implementation of Script::initialiseClasses()
- Removed some duplicate code
svn-id: r54282
- Maintain the state of the string heap space in saved games
- Merged SegManager::reconstructScripts() inside SegManager::saveLoadWithSerializer()
- Disabled a now unnecessary script patch for the cipher puzzle in Castle of Dr. Brain, and performed some cleanup for another disabled patch
- Removed direct access to the _baseObj variable of objects
svn-id: r54133