So, we smoothly move to the topic of engines. Let's go back to the beginning and recall 4 directories with interfaces. Expanding any, we will see the whole structure of the engine: classes and variables.
Class structure
Each engine class in the union has a strict ordering of declaration:
—
Declarator(for example
zCLASS_DECLARATION)
—
Structures and enumerators (class, struct, union, enum, typedef)
—
Fields(
int indexBegin[
DIMENSION])
—
Methods(
void Insert(
void* ) zCall( 0x0063B3B0 ))
—
Virtual methods (
virtual void SetVisual(
zSTRING const& )
zCall(
0x00637160 ))
—
Static methods (
static int ArrayCompare(
void const*,
void const* )
zCall(
0x0063B1B0 ))
—
Static properties (
static zCBBox3DSorterBase*& s_currentSorter)
It is worth noting that the latter (as well as declarators, since they include static variables) are defined by reference. Their definitions are in the classDef_VerX.cpp and staticDef_VerX.cpp files.
Note: each class has a fully public access level, it seemed to me the most convenient option in terms of usability.
Engine function calls
Each class method defines a
zCall statement. It tells the plugin that the call to this function should be carried out at the specified address in the engine. There are three exceptions:
— he class constructor uses an initialization function with a
zInit on the method that calls
zCall.
— If there is no default class constructor, such a constructor is left without instructions.
— A purely virtual method. It uses the
zPureCall instruction.
Also
zCall is not used (but exists) in virtual methods, where
this is defined in the engine. When calling such a method, the call goes by the pointer to vtable and by the offset to a specific function. And if the instance is created in the plugin, then the calls will go through
zCall (because a new pointer to the vtable is created inside the dll).
Global variables
This is a series of variables used by the engine permanently
For example
zCView* screen plays the role of a viewport, and
zCParser* parser is responsible for the operations of Gothic.DAT scripts.
A list of global variables can be found in
zGlobal.h of each engine.
Inclusion and exclusion of engine modules from building
The engine API is very large, so compilation time can take a lot of time, especially for cross-platform plugins. You can speed up the assembly by disabling unused engine modules. For each engine, there is a zEngine.h file, where its blocks are limited by the #if top-level directives. Each of the blocks can be disabled by the #if False construct. Also, disabling will be followed by all blocks dependent on the current.
IMPORTANT: When choosing a project configuration for a specific engine, all blocks that are not related to the selected engine are disabled. That is, if the G2A Release configuration is set, then only Gothic II: NoTR blocks will remain active. We will consider this in another topic.
External symbols table
We call it simply 'Names' or 'Gothic names'. The file itself is called engineNames_VerX.hpp.t contains information about all the names of the engine. It is extremely convenient, as it allows you to quickly find the desired character, address or signature. In the future, we will use it to hook functions