OK. I'll explain how an OP2 DLL works. There are several exported functions in an OP2 mission DLL. (if you don't know what exports, functions, entry points, sections, etc are, go read a C/C++/ASM tutorial.... they'll explain it somewhat. Also, at msdn.microsoft.com search for "PE File Format" and read the MSDN magazine articles "Peering Inside the PE" Part 1 and 2.)
If you have ever looked at the function names using a tool like depends that comes with MSVC++6, you'll see the names of the functions. I'll explain what each one is for:
When I use the word "mission", assume I am referring to any type of scenario (tutorial, colonygame, multi, etc) unless otherwise specified.
First I'll explain the exported variables (these aren't executable code, just entry points to text strings or some other data type)
MapName is the name of the .map file that the mission uses. We have been editing this forever, all current "new maps" just take a mission DLL and edit this string in the .rdata section for the new map file. This can also be referring to
In C++ this would look like:
extern "C" char MapName[] = "Filename.map";
LevelDesc is the description that you see in Outpost 2 when you go to play a mission, in the listing. (For example, the LevelDesc of t01.dll reads "Tutorial 1 - Navigating the Map")
This is unimportant to OP2, it is only a description for humans.
In C++ this looks like
extern "C" char LevelDesc[] = "Description goes here";
TechtreeName refers to the file within Sheets.vol that contains the particular techtree information, like research etc.
(That's how the tutorials have a limited tech tree, they use a different tech tree file than the full missions)
Currently the only techtrees that can be used (until we reverse engineer the encoding in the text files) are the following:
tutortek.txt - Tutorial limited tech tree
multitek.txt - General purpose techtree, used in multiplayer and colony games
edentek.txt - Eden Campaign tech tree
ply_tek.txt - Plymouth Campaign tech tree
The OP2 demo also has a demo tree,
demotek.txt. However this is NOT in the full game (and copying it into the VOL's will not work since it isn't encoded like the full game files are)
In C++ this is:
extern "C" char TechtreeName[] = "TECHNAME.TXT";
And now the last variable export,
DescBlock. This is what controls what kind of game it is. The DescBlock is different for each type. This is also one of the factors that controls whether it shows in the lists; that's why simply putting a "t", "c", "m" or other letter before a DLL name will not make it show in the list. (But that is still used as well, to determine placement in the lists, along with the DescBlock.)
The DescBlock is a 4 byte (
int in C++) that tells OP2 what type of mission.. This could have some work done to decode what each of the bits, etc mean.
Now onto the actual functions that do the work in the mission file.
The single most important export in an OP2 DLL is the
InitProc. OP2 calls this when the mission is loaded, and it "starts" the mission. In the InitProc code, the exported functions from OP2 (take a look at outpost2.exe from depends; there are over 300 exported class members etc) are called to do everything from setup of players to creating units and beacons to setting victory/failure conditions and triggers. (I'll explain triggers in greater depth later, little I know about them)
The InitProc returns a BOOL, which in C++ can be either True (1) or False (0). If it returns 1, that means OP2 will execute the mission. If it returns 0, this is a signal to OP2 that an error occurred and OP2 will stop loading the mission (and display an error message, something along the lines of "Could not initialize script file" or something like that). (By the way, OP2 refers the little it does in errors, etc., to DLL's as "Scripts". I don't use that term.. because technically it's not a script... but OP2 does...)
This is one of the major areas of concern for OP2.. We want to figure out what all the functions mean that are called from InitProc.
Now I'll explain triggers before I go into the less significant functions.
All a trigger is a condition that has some sort of action attached to it that will happen if the conditions are true.
In OP2, there are 17 known types of triggers: Attacked, BuildingCount, Count, Damaged, Escape, Evac, Kit, Midas, OnePlayerLeft, Operational, Point, Rect, Research, Resource, Set, Time, and VehicleCount. (No I don't know what each one does or how to set one up, but I know that you can create them in OP2.)
The "action" for OP2 triggers is contained in another exported function called a
callback. For those of you not familiar with callbacks, a callback is a function or piece of code that is called/run when it needs to. OP2 calls the callback that is assigned to a trigger when that trigger's condition becomes true, and then that can do certain things (for example, if you get 1000 metals, it creates a building or who knows what)
You can see the names of these callbacks in depends, they are exported along with the other functions.
Victory and failure conditions work on triggers. When a victory/failure condition is created, you assign it a trigger. If that trigger become true (is fired), then that means the victory or failure condition is satisfied, and the game ends at that point if all the victory or failure conditions are satisfied.
In the OP2 DLL's you will see the developers put a function in almost every DLL named
NoResponseToTrigger. All it is is a function that takes nothing as a parameter, and returns nothing. It's mainly used when you have a trigger that is also used as the victory/failure condition, and you don't need it to do anything. Also you must assign it a trigger, so you just give it a trigger that is "empty". Usually the NoResponseToTrigger is a Time type.
In C++, NoResponseToTrigger looks like this:
void NoResponseToTrigger(void) {
}
Now, onto the less important functions, that are less well known.
AIProc appears to be a function that was going to originally be used in OP2, but it isn't needed because of the trigger system and more advanced AI. So AIProc looks like NoResponseToTrigger - it takes nothing as a parameter, does nothing, and returns nothing. In C++ it looks like this:
StatusProc appears to be something that tells OP2 if some error or other bad thing happened. Normally, it returns 0. In C++ it would look like this:
BOOL StatusProc(void) {
return FALSE;
}
The last function,
GetSaveRegions, is totally unknown. It doesn't exist in all missions, and I'm not sure of what it does (it only has like 4 lines of assembly code), or even what it takes/returns. I have no information on it otherwise.
Well, that's the information I have on DLL's. Happy hacking!
-- op2hacker