

Outpost 2 Saved Game File Format
--------------------------------

Note: Saved games share much of the same loading code as the .map file format.
They consist of a prefix to the .map format and (possibly) some data near the end.

Note: Brett 24JUN17
      The name of the saved game starts at offset 0x25. 
      Max size of the name is 31 characters.

Outpost 2 .op2 File Format (Saved Games)
----------------------------------------

Offset  Size    Description
------  ----    -----------
0x0     0x19    "OUTPOST 2.00 SAVED GAME", 0x1A, 0 - String must match exactly or else load error
---------------------------
0x19    0x1086C fileDialogData
0x10885 0xD7A0  sheetData[0x73]  (array of 0x73 (115) UnitTypeInfo objects, each loading 0x1E0 bytes of data)
        Note: Technically each object loads data through a virtual function call, so each object could load a different amount of data. However, there are no overrides, so they all call the same base class function, and hence all load the same data.
          4       int requiredTechNum
          0x1DC   struct[] unitTypeInfo.playerInfo[]
---------------------------
0x1E025 ...     From here, the format matches that of .map files



Outpost 2 .map File Format
--------------------------

Note: Logs discussed below are all base 2 logarithms.



Offset 	Size 	Description
------ 	---- 	-----------
		Section: Header
0x0 	4 	DWORD openingTag	[Must be >= 0x1010 or load is aborted]
0x4 	4 	bool bSavedGame		[Must be set for saved games or laod is aborted]
0x8 	4 	lgMapTileWidth		[Base 2 log of map tile width]
0xC 	4 	mapTileHeight		[This value gets rounded up to a power of 2]
0x10 	4 	numTileSets
---------------------------
		Section: Tile Data
0x14 	X 	tileData - array of DWORDs of size mapTileWidth*mapTileHeight
			The tileData consists of the following bit fields
			5	CellType - determines speed of movement, bulldozed, walled, tubed, rubble areas (see Note below) (returned by GameMap.GetCellType)
			11	TileIndex - this is an index into the tileInfo array described below (see Tile Set Section)
			11	UnitID - unitID (index of unit into unit array) of the unit that occupies this tile
			1	Lava - Indicates the presence of Lava
			1	LavaPossible - indicates that lava can spread to this tile
			1	Expansion - Used to control the spread of Lava and Microbe **TODO** figure out how it works [Used to display computer overlay]
			1	Microbe - Indicates the presence of the Blight
			1	Wall/Building - a NormalWall, LavaWall, MicrobeWall, or a building (partially built/dismantled or complete) has been built on this tile
---------------------------
		Section: ClipRegion
X+0x14 	4 	clipRegion.x1 - (0x20, internal coordinates of left edge, or -1 for around the world maps)
X+0x18 	4 	clipRegion.y1 - (0 = 1-1)
X+0x1C 	4 	clipRegion.x2 - (mapTileWidth + 0x1F, internal coordinates of rightmost tileX) or (0x7FFFFFFF if logTileWidth >= 9, around the world maps)
X+0x20 	4 	clipRegion.y2 - (tileHeight-2 = (tileHeight-1) - 1)
---------------------------
		Section: Tile Set Sources
X+0x24 	Y 	tileSetSource table (refers to the "well00??.bmp" files)
			The tile set source table has up to 3 fields for each entry of the table
			4 	stringLength - length of filename
			8 	tileSetFilename
			4 	numTiles - number of tiles in this tile set
		Note: The last two fields will not exist if the first field, stringLength == 0.
		The game will attempt to read numTileSets (see Header Section) copies of these fields. 
		It will read 16 bytes for the fields were a string exists (stringLength != 0) 
		and 4 bytes where the string doesn't exist (stringLength == 0).
---------------------------
			Section: Tile Set
	0xA 		"TILE SET", 0x1A, NULL (10 characters, 0x1A, NULL terminated string) - Loading fails if string doesn't match
	4 		numTiles - Specifies how many tiles from the loaded tile sets are referenced
	8*numTiles	tileInfo array - tileData array (see Tile Data Section) indexes into this array to find tile graphic
				The tileInfo array consists of an array of the following structure
				2	tileSetIndex	- index of tile set (see Tile Set Sources Section)
				2	tileIndex	- index of the tile in this tile set (tileIndex to tileIndex+numAnimations can be used)
				2	numAnimations	- number of following tiles that can be displayed to replace this one (See TileSet7 for more details TileNum 0) or CodeSection 0x0047030D
				2	animationDelay	- number of cycles elapsed before displaying next tile (See TileSet7 for more details TileNum 0)
	4 		numTerrainTypes
	0x108*numTerrainTypes	Array of TerrainType objects - (list of tile indexes, provides mappings to new tile indexes when graphics change. eg. bulldozed, tube/wall built)
				2	startTileIndex	- first tile index to which this list applies
				2	endTileIndex	- last tile index to which this list applies
				2	bulldozedTileIndex	- tile index to set when tiles in this group are bulldozed
				2	rubbleTileIndex - index of common rubble tile (4 consecutive common rubble tiles followed by 4 rare rubble tiles)
				2*6	tubeTiles[6]	- index of tube tiles (data is repeated **TODO** find out why)
				32*5	wall[5][16]	- arrays of wall tile groups (16 tiles in each array)
				2	lava		- starting lava tile index
				2	flat1		- **TODO** find out how they're used
				2	flat2		- **TODO** find out how they're used
				2	flat3		- **TODO** find out how they're used
				32	tube[16]	- array of tube tile indexes (for tubes facing each direction)
				2	scorched	- scorched tile index (from vehicle explosion, or meteor impact)
				12	scorchedRange[3]
				 2	 startTile
				 2	 endTile
				30	unknown[15]	- **TODO** find out - various tile indexes, or 0
---------------------------
	4	tag - must match tag at first DWORD of .map file else error (see Header Section)
---------------------------
	Note: Extra data is read here for Saved Games. Map files do not contain this section of data.
	4	numUnits
	4	lastUsedUnitIndex
	4	nextFreeUnitSlotIndex
	4	firstFreeUnitSlotIndex
	4	sizeofUnit - 0x78 (120 bytes) if sizeofUnit != 0x78 && numUnits != 0 then Error
- - - - - - - - - - - - - -
	Note: Reading continues here in a subroutine at 0x00446CF0
	4	numObjects1 (number of 512 byte objects)
	4	numObjects2 (number of 4 byte objects)
	Note: if (numObjects1 == 0) return (successfully)
	512*numObjects	objectArray **TODO** find out what this object is
	Note: if (numObjects2 == 0) return (successfully)
	4*numObjects2	objectArray **TODO** find out what this object is
	Note: End of subroutine read
- - - - - - - - - - - - - -
	4	unitID - nextUnitIndex
	4	unitID - prevUnitIndex
	UnitArray (pre and post unit limit patch) sizeof(unitRecord) = 120 bytes:
		0x1DF88	UnitRecord[1023] unitArray - Original (pre unit limit patch)
		0x3BF88	UnitRecord[2047] unitArray - Updated (post unit limit patch)
- - - - - - - - - - - - - -
	Optional: This section is only read if (firstFreeUnitSlotIndex != nextFreeUnitSlotIndex)
	0x2000 Unit*[2048] unitFreeList
- - - - - - - - - - - - - -
	Note: End of Saved Game specific data section. Map and Saved Game data continue from here.
---------------------------
	4	tag - must match tag at first DWORD of .map file else error (see Header Section)
	Note: End of .map load. (Outpost2.exe does not load .map data beyond this point)
---------------------------
	Additional data: This is found only in saved game files
		MessageLog
		LevelDLL
		Player[]
		Research
		DayNight
		UnitHotKeyGroups
		DetailPane
		RandomNumberGenerator
		Lava
		Blight
---------------------------
	Extra data: This is found in .map files, but is not loaded or processed by Outpost2.exe.
	Each tile group is tagged with a name (eg. "LAVA_LEFT", "midd_lava", "RIGHT_LAVA", etc.)
		4	uint numTileGroups
		4	uint maxTileGroups
- - - - - - - - - - - - - -
	A list of the following items is found
		4		dim1 size
		4		dim2 size
		4*dim1*dim2	int data[dim1][dim2]
		4		stringLen
		stringLen	string
- - - - - - - - - - - - - -
	End of .map file




Loading Notes:
--------------
The numTiles in the Tile Set section are read into an array, processed, and then released from 
memory. Processing differs depending on whether or not numTiles == 0. The
element at index 7 (the lava tile set) is special cased.


Note: cellType (5 bits) has one of the 32 following meanings, as can be found at [0x4DEBA8]:
Value    	Meaning
-------- 	-------
0 (0x0) 	Fast Passable 1		- rock vegetation
1 (0x1) 	Impassible 2		- meteor craters, cracks/crevasses
2 (0x2) 	Slow Passable 1		- lava rock (dark)
3 (0x3) 	Slow Passable 2		- rippled dirt/lava rock bumps
4 (0x4) 	Medium Passable 1	- dirt
5 (0x5) 	Medium Passable 2	- lava rock
6 (0x6) 	Impassible 1		- dirt/rock/lava rock mound/ice cap/volcano
7 (0x7) 	Fast Passable 2 	- rock
8 (0x8) 	North Cliffs		- 
9 (0x9) 	Cliffs - High side	- 
10 (0xA) 	Cliffs - Low Side	- cliffs, low side (and middle too)
11 (0xB) 	Vents and Fumaroles	- fumaroles (only passable by GeoCons/RoboMiners?)
12 (0xC) 	zPad 12
13 (0xD) 	zPad 13
14 (0xE) 	zPad 14
15 (0xF) 	zPad 15
16 (0x10) 	zPad 16
17 (0x11) 	zPad 17
18 (0x12) 	zPad 18
19 (0x13) 	zPad 19
20 (0x14) 	zPad 20
21 (0x15) 	Dozed Area 		- bulldozed, non tubed area (buildings are tubed underneath) - does not include buildings
22 (0x16) 	Rubble
23 (0x17) 	Normal Wall
24 (0x18) 	Microbe Wall
25 (0x19) 	Lava Wall
26 (0x1A) 	Tube0 			- tubed (buildings are tubed underneath, including docks) - includes buildings
27 (0x1B) 	Tube1
28 (0x1C) 	Tube2
29 (0x1D) 	Tube3
30 (0x1E) 	Tube4
31 (0x1F) 	Tube5
