Decompiler

With SCICompanion you can decompile Sierra games to see how they work! This is a vast improvement over just disassembling scripts, as it uses control flow analysis to reconstruct higher level structures like if statement, switch statements, while loops and more. The result is something fairly readable.

Sierra’s script resources still contain a significant amount of original information. Class and instance names are preserved, as are property and method names. And of course, we can figure out the kernel function call names. The names of parameters, script and temp variables aren’t available, but we can make some guesses based on how they are used, and what values are assigned to them.

Decompilation was used as a base to generate the SCI 1.1 template game. It can also just be used to see how scripts worked, or to find easter eggs, or even to modify the logic to fix bugs in the original Sierra games.

Here’s an example of a decompiled nextCel method from Space Quest 4’s Cycle class:

(method (nextCel)
       (++ cycleCnt)
       (return
           (if (<= cycleCnt (client cycleSpeed?))
               (client cel?)
           else
               (= cycleCnt 0)
               (if (& (client signal?) $1000)
                   (client cel?)
               else
                   (+ (client cel?) cycleDir)
               )
           )
       )
   )

And then the same method simply disassembled:

   (method (nextCel)
       (asm
           ipToa   cycleCnt
           pTos    cycleCnt
           pushi   #cycleSpeed
           pushi   0
           pToa    client
           send    4
           le?
           bnt     code_002e
           pushi   #cel
           pushi   0
           pToa    client
           send    4
           jmp     code_0056
code_002e: ldi     0
           aTop    cycleCnt
           pushi   #signal
           pushi   0
           pToa    client
           send    4
           push
           ldi     4096
           and
           bnt     code_004b
           pushi   #cel
           pushi   0
           pToa    client
           send    4
           jmp     code_0056
code_004b: pushi   #cel
           pushi   0
           pToa    client
           send    4
           push
           pToa    cycleDir
           add
code_0056: ret
       )
   )

You can see how much easier the decompiled code is to understand!

The Decompile dialog

All decompilation starts with the Decompile dialog, accessed from Script->Manage Decompilation. This presents you with a list of scripts in the game, and whether or not there are source code (.sc) or .sco files for each of them.

_images/DecompileDialog.jpg

Script filenames

The first thing you should do when decompiling a game is to generate good filenames for the original script files. This can be done with the Set Filenames button, which will analyze the script resources and try to generate a filename based on the contents of the script.

You can rename a script by clicking on it in the script list and pressing F2 (you can also do this from the scripts tab in the game explorer).

Decompiling a script

You can select one or more scripts on the left (using shift-click), and then press the Decompile button. Decompiling a script is complex and can be a fairly lengthy process, so if you’re only curious about a few scripts, then just select those. As the decompilation takes place, status updates are given in the pane on the right.

If you want to decompile the entire game of course, then just select all scripts, click Decompile and sit back. Decompiling a typical entire Sierra game should take about a minute or so.

When a script is decompiled, we also generate the .sco file for it. This contains the “public” information in the script (such as the names of procedures that it exports) which is used by other scripts. You’ll need these .sco files if you want to then go in and make changes to the scripts and successfully recompile.

Public procedure names and variable names

SCICompanion will try to guess good variable names. For temp and parameter names, you have no control over the the names that are used.

However, for script-wide variables and procedure names, we will place these “guessed” names in the .sco file. You can edit these names in the SCO pane to make them more meaningful, and then any script that references that script will pick up those new names when it is decompiled again.

When SCICompanion encounters other scripts using a global variable (from script 0, main.sc) that still has the default name (e.g. global30), it will try to give that variable a name based on its usage. That means that as you decompile more scripts, the names of the global variables in main.sc may change (i.e. improve).

So to get a complete decompile, it is recommended to run the decompilation steps a second time on all files so that they pick up any new names for global variables (and any names for procedures that you have entered).

Accuracy

Decompilation is not a perfect science, and there will be situations where SCICompanion is not able to reconstruct the high level language conditional structures. In that case, the code for a method or procedure will fall back to disassembly (in an asm block). In general, this should only happen for about 2% to at most 5% of the total code in a game.

There may still be some bugs in the resultant decompiled code, so if you recompile a script and suddenly the game starts behaving strangely, that is a likely suspect. If you encounter this, please send a bug report. If you understand SCI byte code, you can also compare a method’s code with its disassembled version (which is much easier to get 100% correct) to see if anything looks wrong. If you check the Disassembly only box in the Decompile Dialog, this will force SCICompanion to fallback to assembly for every method or procedure.