Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   Compound Members   Related Pages  

Advanced - Patching

KC Patches

Purpose

To make patches which can be used with old save games, KC programs must be compiled with certain options. The code which is added after a previous patch, must be specially marked for the compiler, so that it can produce patch tables which can in turn be used by the runtime system to load an old savegame and correct jump addresses and reuse old loaded strings.

Keywords

The following keywords are used to mark patches:

#pragma defpatch patchversion patchcompiletime

patchversion is one in a series of integers, starting with 0 for the master version. patchcompiletime is the date of compilation for the patch version, as returned by time(). A compiled story contains its compile time. Also, the symbol _COMPILE_TIME_ is defined at compile time. The save games also contain the compiletime of the story version with which they were saved.

#pragma patch patchversion

... new code goes here ...

#pragma endpatch

Marks a section of new code that was inserted for patch version patchversion.

Patch sections can be nested, but then the inner patch version must be higher than the outer patch version. Code that is present after patch 1 is also present after patch 2 and further patches.

Rules for added code

Patch code can always only be added to the last version, never replace existing code. One or several lines of patch code can be inserted at a certain location in the current code, but there are several requirements for the new patch code as well as the existing code.

There are several possible locations where to enter new code easily:

1. class level

A new class is defined inside the patch section, complete with local functions, variables and code.

#pragma patch 1
class OBJ_DUMMY
{
    int foo() {
        ...
    }
}
#pragma endpatch

2. global function level

Same level as class level, new global functions can be added enclosed in a patch section.

class OBJ_DUMMY
#pragma patch 1
int global_foo() {
    ...
}
#pragma endpatch

3. class function level

A new class member function can be added inside a class.

class OBJ_DUMMY
{
    int foo() {
        ...
    }
#pragma patch 1
    int foo2() {
        ...
    }
#pragma endpatch
}

4. Statements inside a function

The statements may not change the logic of the surrounding code, and they may not contain variable definitions.

class OBJ_DUMMY
{
    int foo() {
        int a = 3;
        int b = 4;
#pragma patch 1
        b = a * b;  // Correct use of patch
#pragma endpatch
        a = a + 5;
    }
    int foo2() {
        int a = 3;
        int b = 4;
#pragma patch 2
        int c = a * b;  // Wrong use, because variable c is defined
#pragma endpatch
        a = a + 5;
    }
    int foo3() {
        int a = 3;
        int b = 4;
        if (a == d)
#pragma patch 3
            c = a * b;  // Wrong use, changes the if statement
#pragma endpatch
            a = a + 5;
    }
}

5. Complete block inside a function

Anything can be done inside the block, including local variable definitions.

class OBJ_DUMMY
{
    int foo() {
        int a = 3;
        int b = 4;
#pragma patch 1
        {
            int c = a * b;  // Correct use of patch
            a = foo2(c);
        }
#pragma endpatch
        a = a + 5;
    }
    int foo2() {
        int a = 3;
        int b = 4;
#pragma patch 2
        if (a == d) {
            int c = a * b;  // Correct, if-statement is a block
            a = foo2(c);
        }
#pragma endpatch
        a = a + 5;
    }
}

Free patches

There are several type of changes that can be done without #pragma statements:

Pitfalls

Tips


Generated on Mon Aug 26 18:26:35 2002 for X² KC by doxygen1.2.17