Author Topic: Descblock(ex)  (Read 1519 times)

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Descblock(ex)
« on: July 09, 2008, 07:24:25 PM »
From the SDK header, we have:

Code: [Select]
struct SDescBlock{
int missionType;   // Mission type (defined above) or mission number (positive values) for campaign games
int numPlayers;    // Number of players (on a multipalyer map)
int maxTechLevel;   // Maximum tech level (Set to 12 to enable all techs)
int boolUnitMission;  // Set to 1 to disable most reports (suitable for unit-only missions)
};

From code inside Outpost2.exe, it seems there are an extra 3 fields in this struct. (This is based of a mem copy of 7 dwords). They are:

Code: [Select]
char* mapName;
char* levelDesc;
char* techTreeName;

However, these 3 values are also exported, and the exported values, or rather string copies of them, overwrite those extra 3 fields before they're used. So, it doesn't matter really if we keep this definition, or use the other one. Although, I get the feeling the SDK header used to declare this struct with the extra fields, but they were removed for some reason. Perhaps because they're useless and redundant? Or maybe because we thought we messed up with the exact correctness when we hadn't.


As for DescBlockEx, the only reference I saw to it has exactly one field read. This field is the number of AI players. I remember seeing a DescBlockEx struct posted on here with a rather large block of unknown fields, but I'm not aware of any evidence suggesting it has more than 1 field.


In a related matter, there is also an AIModDesc struct, which isn't particularly relevant for level building, only for the shell. It seems to contain a DescBlock struct along with a checksum field at the end.
 

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Descblock(ex)
« Reply #1 on: July 12, 2008, 04:02:41 AM »
I just had a stunning realization. The struct that we named SDescBlock in the SDK is probably actually an AIModDesc struct.


Why? Well, for one, the name SDescBlock doesn't seem to be an official name I've seen anywhere encoded in the decorated names from Outpost2.exe. It's just something we came up with to describe the structure of the DescBlock entry. I did a quick search of the SDK header files, and a dump of the exported names, just to be sure it wasn't used anywhere outside of where we named it. But the name AIModDesc is actually found encoded in those exported symbols. Also, the exported name DescBlock is a variable name, not a structure name. It seems we just say the variable name and inferred a structure name.

When considering the memory layout of a data section from an official DLL, it would make sense that these two structs are the same size, and quite possibly the same struct. When searching for references to bytes starting at the DescBlock address, there are none found until after the full size of AIModDesc are accounted for. That "extra" checksum field that I mentioned in the previous post is just filled with zeros. It's not until after that field that data gets referenced. This suggests that all that data is part of the same struct, and is accessed as an offset from the base address.

I also considered alignment padding, but there doesn't seem to be any reason to add any. It looks very much like that field was intended to be there.


There is one slight hole in my theory though. That's the mem copy of 7 dwords that I saw. Such a mem copy is usually only seen when you copy structs, such as provided by the default assignment operator, or the default copy constructor. That suggests there is a 7 dword struct involved in the copy. However, that 7 dword struct could easily be some sub struct. Perhaps it looks something like this:

Code: [Select]
struct AIModDesc
{
 struct
 {
  int missionType;   // Mission type (defined above) or mission number (positive values) for campaign games
  int numPlayers;    // Number of players (on a multipalyer map)
  int maxTechLevel;   // Maximum tech level (Set to 12 to enable all techs)
  int boolUnitMission;  // Set to 1 to disable most reports (suitable for unit-only missions)
  char* mapName;
  char* levelDesc;
  char* techTreeName;
 } DescBlock;
 int checksum;
};


At any rate, it still seems that the exported data structure is really an 8 dword sized struct.