.. Decompiler

.. include:: /includes/standard.rst

================
 Decompiler
================

With |scicomp| 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.

.. image:: /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
-----------------------------------------

|scicomp| 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 |scicomp| 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 |scicomp| 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 |scicomp| to fallback to assembly for every method or procedure.

