fixed swapped metal and plant matgloss, got rid of deprecated old stuff

develop
Petr Mrázek 2009-10-28 15:40:10 +00:00
parent b7780e2dc6
commit adb33b88f9
10 changed files with 1 additions and 2042 deletions

@ -169,13 +169,12 @@ case 24:
*/
// FIXME: in order in which the raw vectors appear in df memory, move to XML
enum MatglossType
{
Mat_Wood,
Mat_Stone,
Mat_Plant,
Mat_Metal,
Mat_Plant,
Mat_Leather = 10,
Mat_SilkCloth = 11,
Mat_PlantCloth = 12,

@ -1,661 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "DFCommon.h"
// zlib helper functions for de/compressing files
#include "ZlibHelper.h"
#include "DfMapHeader.h"
// some bounds checking in debug mode. used in asserts
#define CheckBounds x < x_cell_count && x >= 0 && y < y_cell_count && y >= 0 && z < z_block_count && z >= 0
#define CheckBoundsXY x < x_cell_count && x >= 0 && y < y_cell_count && y >= 0
#define CheckBlockBounds x < x_block_count && x >= 0 && y < y_block_count && y >= 0 && z < z_block_count && z >= 0
// this expands into lots of ugly switch statement functions. some of them unused?, but kept for reference
#include "DFTileTypes.h"
// process vein vector into matgloss values...
void Block::collapseVeins()
{
// iterate through assigned veins
for( uint32_t i = 0; i < veins.size(); i++)
{
t_vein v = veins[i];
//iterate through vein assignment bit arrays - one for every row
for(uint32_t j = 0;j<16;j++)
{
//iterate through the bits
for (uint32_t k = 0; k< 16;k++)
{
// and the bit array with a one-bit mask, check if the bit is set
bool set = ((1 << k) & v.assignment[j]) >> k;
if(set)
{
material[k][j].type = Mat_Stone;
material[k][j].index = v.type;
}
}
}
}
}
DfMap::~DfMap()
{
clear();
}
/// TODO: make this sync
void DfMap::clear()
{
if(valid)
{
valid = false;
for(uint32_t i = 0; i < x_block_count*y_block_count*z_block_count;i++)
{
Block * b = block[i];
if(b!=NULL)
{
delete b;
}
}
delete[] block;
}
for (uint32_t i = eNorthWest; i< eBiomeCount;i++)
{
v_geology[i].clear();
//geodebug[i].clear();
//geoblockadresses[i] = 0;
//regionadresses[i] = 0;
}
for(uint32_t counter = Mat_Wood; counter < NUM_MATGLOSS_TYPES; counter++)
{
v_matgloss[counter].clear();
}
// delete buildings, clear vector
for(uint32_t i = 0; i < v_buildings.size(); i++)
{
delete v_buildings[i];
}
v_buildings.clear();
// delete vegetation, clear vector
for(uint32_t i = 0; i < v_trees.size(); i++)
{
delete v_trees[i];
}
v_trees.clear();
// clear construction vector
v_constructions.clear();
blocks_allocated = 0;
///FIXME: destroy all the extracted data here
}
void DfMap::getRegionCoords (uint32_t &x,uint32_t &y,uint32_t &z)
{
x= regionX;
y= regionY;
z= regionZ;
}
void DfMap::setRegionCoords (uint32_t x,uint32_t y,uint32_t z)
{
regionX = x;
regionY = y;
regionZ = z;
}
void DfMap::allocBlockArray(uint32_t x,uint32_t y, uint32_t z)
{
clear();
x_block_count = x;
y_block_count = y;
z_block_count = z;
updateCellCount();
block = new Block*[x_block_count*y_block_count*z_block_count];
for (uint32_t i = 0; i < x_block_count*y_block_count*z_block_count; i++ )
{
block[i] = NULL;
}
blocks_allocated = 0;
valid = true;
}
DfMap::DfMap(uint32_t x, uint32_t y, uint32_t z)
{
valid = false;
allocBlockArray(x,y,z);
}
DfMap::DfMap(string FileName)
{
valid = false;
valid = load( FileName);
}
bool DfMap::isValid ()
{
return valid;
}
Block * DfMap::getBlock (uint32_t x,uint32_t y,uint32_t z)
{
if(isValid())
{
return block[x*y_block_count*z_block_count + y*z_block_count + z];
}
return NULL;
}
vector<t_building *> * DfMap::getBlockBuildingsVector(uint32_t x,uint32_t y,uint32_t z)
{
Block * b = getBlock(x,y,z);
if(b)
{
return &b->v_buildings;
}
return NULL;
}
vector<t_tree_desc *> * DfMap::getBlockVegetationVector(uint32_t x,uint32_t y,uint32_t z)
{
Block * b = getBlock(x,y,z);
if(b)
{
return &b->v_trees;
}
return NULL;
}
t_tree_desc *DfMap::getTree (uint32_t x, uint32_t y, uint32_t z)
{
for(uint32_t i = 0; i< v_trees.size();i++)
{
if(x == v_trees[i]->x
&& y == v_trees[i]->y
&& z == v_trees[i]->z)
{
return v_trees[i];
}
}
return 0;
}
t_building *DfMap::getBuilding (uint32_t x, uint32_t y, uint32_t z)
{
for(uint32_t i = 0; i< v_buildings.size();i++)
{
if(x >= v_buildings[i]->x1 && x <= v_buildings[i]->x2
&& y >= v_buildings[i]->y1 && y <= v_buildings[i]->y2
&& z == v_buildings[i]->z)
{
return v_buildings[i];
}
}
return 0;
}
Block * DfMap::allocBlock (uint32_t x,uint32_t y,uint32_t z)
{
if(isValid())
{
if(block[x*y_block_count*z_block_count + y*z_block_count + z])
{
return block[x*y_block_count*z_block_count + y*z_block_count + z];
}
Block *b = new Block;
block[x*y_block_count*z_block_count + y*z_block_count + z] = b;
blocks_allocated++;
return b;
}
return NULL;
}
void DfMap::updateCellCount()
{
x_cell_count = x_block_count * BLOCK_SIZE;
y_cell_count = y_block_count * BLOCK_SIZE;
z_cell_count = z_block_count;
}
void DfMap::applyGeoMatgloss(Block * b)
{
// load layer matgloss
for(int x_b = 0; x_b < BLOCK_SIZE; x_b++)
{
for(int y_b = 0; y_b < BLOCK_SIZE; y_b++)
{
int geolayer = b->designation[x_b][y_b].bits.geolayer_index;
int biome = b->designation[x_b][y_b].bits.biome;
b->material[x_b][y_b].type = Mat_Stone;
b->material[x_b][y_b].index = v_geology[b->RegionOffsets[biome]][geolayer];
}
}
}
uint8_t DfMap::getLiquidLevel(uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return b->designation[x2][y2].bits.flow_size;
}
return 0;
}
uint16_t DfMap::getTileType(uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return b->tile_type[x2][y2];
}
if(isTileSky(x,y,z,x2,y2))
{
return 32;
}
return -1;
}
uint16_t DfMap::getTileType(uint32_t x, uint32_t y, uint32_t z, uint32_t blockX, uint32_t blockY)
{
assert(CheckBlockBounds);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return b->tile_type[blockX][blockY];
}
if(isTileSky(x,y,z,blockX,blockY))
{
return 32;
}
return -1;
}
uint32_t DfMap::getDesignations(uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return b->designation[x2][y2].whole;
}
return -1;
}
bool DfMap::isBlockInitialized(uint32_t x, uint32_t y, uint32_t z)
{
// because of the way DfMap is done, more than one check must be made.
return getBlock(x,y,z) != NULL;
}
uint32_t DfMap::getOccupancies(uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return b->occupancy[x2][y2].whole;
}
return -1;
}
void DfMap::getGeoRegion (uint32_t x, uint32_t y, uint32_t z, int32_t& geoX, int32_t& geoY)
{
assert(CheckBoundsXY);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
int biome = b->designation[x2][y2].bits.biome;
int BiomeOffset = b->RegionOffsets[biome];
int16_t X_biomeB = (regionX / 16) + (BiomeOffset % 3) - 1;
int16_t Y_biomeB = (regionY / 16) + (BiomeOffset / 3) - 1;
if(X_biomeB < 0) X_biomeB = 0;
if(Y_biomeB < 0) Y_biomeB = 0;
if( (uint32_t)X_biomeB >= worldSizeX)
{
X_biomeB = worldSizeX - 1;
}
if( (uint32_t)Y_biomeB >= worldSizeY)
{
Y_biomeB = worldSizeY - 1;
}
geoX = X_biomeB;
geoY = Y_biomeB;
}
else
{
geoX = regionX / 16;
geoY = regionY / 16;
}
}
t_matglossPair DfMap::getMaterialPair (uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return b->material[x2][y2];
}
t_matglossPair fail = {-1,-1};
return fail;
};
// this is what the vein structures say it is
string DfMap::getGeoMaterialString (uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return getMaterialString(b->material[x2][y2].type, b->material[x2][y2].index);
}
string fallback = "UNKNOWN";
return fallback;
}
string DfMap::getMaterialTypeString (uint32_t type)
{
string ret = "";
switch (type)
{
case 0:
ret += "wood";
break;
case 1:
ret += "stone/soil";
break;
case 2:
ret += "metal";
break;
case 3:
ret += "plant";
break;
case 10:
ret += "leather";
break;
case 11:
ret += "silk cloth";
break;
case 12:
ret += "plant thread cloth";
break;
case 13: // green glass
ret += "green glass";
break;
case 14: // clear glass
ret += "clear glass";
break;
case 15: // crystal glass
ret += "crystal glass";
break;
case 17:
ret += "ice";
break;
case 18:
ret += "charcoal";
break;
case 19:
ret += "potash";
break;
case 20:
ret += "ashes";
break;
case 21:
ret += "pearlash";
break;
case 24:
ret += "soap";
break;
default:
ret += "unknown";
break;
}
return ret;
}
string DfMap::getMaterialString (uint32_t type, uint32_t index)
{
if(index != 65535 && type >= 0 && type < NUM_MATGLOSS_TYPES)
{
if(index < v_matgloss[type].size())
{
return v_matgloss[type][index];
}
else
{
string fallback = "ERROR";
return fallback;
}
}
string fallback = "UNKNOWN";
return fallback;
}
uint16_t DfMap::getNumMatGloss(uint16_t type)
{
return v_matgloss[type].size();
}
string DfMap::getBuildingTypeName(uint32_t index)
{
if(index < v_buildingtypes.size())
{
return v_buildingtypes[index];
}
return string("error");
}
string DfMap::getMatGlossString(uint16_t type,uint16_t index)
{
if(index < v_matgloss[type].size())
{
return v_matgloss[type][index];
}
return string("error");
}
// matgloss part of the designation
unsigned int DfMap::getGeolayerIndex (uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return b->designation[x2][y2].bits.geolayer_index;
}
return -1;
}
// matgloss part of the designation
unsigned int DfMap::getBiome (uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return b->designation[x2][y2].bits.biome;
}
return -1;
}
bool DfMap::isHidden (uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return (b->designation[x2][y2].bits.hidden);
}
return false;
}
bool DfMap::isSubterranean (uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return (b->designation[x2][y2].bits.subterranean);
}
if(isTileSky( x, y, z, x2, y2))
{
return false;
}
return true;
}
// x,y,z - coords of block
// blockX,blockY - coords of tile inside block
bool DfMap::isTileSky(uint32_t x, uint32_t y, uint32_t z, uint32_t blockX, uint32_t blockY)
{
assert(CheckBounds);
Block *b;
// trace down through blocks until we hit an inited one or the base
for (int i = z; i>= 0;i--)
{
b = getBlock(x,y,i);
if(b)
{
// is the inited block open to the sky?
return b->designation[blockX][blockY].bits.skyview;
}
}
// we hit base
return false;
}
// is the sky above this tile visible?
bool DfMap::isSkyView (uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return (b->designation[x2][y2].bits.skyview);
}
if(isTileSky(x,y,z,x2,y2))
{
return true;
}
return false;
}
// is there light in this tile?
bool DfMap::isSunLit (uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return (b->designation[x2][y2].bits.light);
}
return false;
}
bool DfMap::isMagma (uint32_t x, uint32_t y, uint32_t z)
{
assert(CheckBounds);
uint32_t x2, y2;
convertToDfMapCoords(x, y, x, y, x2, y2);
Block *b = getBlock(x,y,z);
if(b != NULL)
{
return (b->designation[x2][y2].bits.liquid_type);
}
return false;
}

@ -1,204 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef DFMAP_H_INCLUDED
#define DFMAP_H_INCLUDED
#define BLOCK_SIZE 16
class DfMapHeader;
class Block
{
public:
// where does the Block come from?
uint32_t origin;
// generic tile type. determines how the tile behaves ingame
uint16_t tile_type[BLOCK_SIZE][BLOCK_SIZE];
t_designation designation[BLOCK_SIZE][BLOCK_SIZE];
t_occupancy occupancy[BLOCK_SIZE][BLOCK_SIZE];
// veins
vector <t_vein> veins;
t_matglossPair material[BLOCK_SIZE][BLOCK_SIZE];
vector<t_building*> v_buildings;
vector<t_tree_desc*> v_trees;
void collapseVeins();
/**
// region offset modifiers... what a hack.
// here we have double indexed offset into regions.
// once inside t_designation, pointing into this, second time from here as a index modifier into region array (2d)
// disassembled code where it's used follows. biome is biome from t_designation
biome_stuffs = *(_BYTE *)((char)biome + offset_Block + 0x1D84);
biome_stuffs_mod3 = biome_stuffs % 3;
biome_stuffs_div3 = biome_stuffs / 3;
biome_stuffs_mod3_ = biome_stuffs_mod3;
if ( !biome_stuffs_mod3_ )
--*(_WORD *)X_stuff;
if ( biome_stuffs_mod3_ == 2 )
++*(_WORD *)X_stuff;
if ( !biome_stuffs_div3 )
--*(_WORD *)Y_stuff_;
if ( biome_stuffs_div3 == 2 )
++*(_WORD *)Y_stuff_;
*/
uint8_t RegionOffsets[16];// idk if the length is right here
};
/**
* This class can load and save DF maps
*/
class DfMap
{
private:
// allow extractor direct access to our data, avoid call lag and lots of self-serving methods
friend class Extractor;
Block **block;
uint32_t blocks_allocated;
bool valid;
// converts the (x,y,z) cell coords to internal coords
// out_y, out_x - block coords
// out_y2, out_x2 - cell coords in that block
inline void convertToDfMapCoords(uint32_t x, uint32_t y, uint32_t &out_x, uint32_t &out_y, uint32_t &out_x2, uint32_t &out_y2)
{
out_x = x / BLOCK_SIZE;
out_x2 = x % BLOCK_SIZE;
out_y = y / BLOCK_SIZE;
out_y2 = y % BLOCK_SIZE;
};
void allocBlockArray(uint32_t x,uint32_t y, uint32_t z);
void updateCellCount();
bool loadVersion1(FILE * Decompressed,DfMapHeader & h);
bool writeVersion1(FILE * SaveFile);
bool loadMatgloss2(FILE * Decompressed);
bool loadBlocks2(FILE * Decompressed,DfMapHeader & h);
bool loadRegion2(FILE * Decompressed);
bool loadVersion2(FILE * Decompressed,DfMapHeader & h);
void writeMatgloss2(FILE * SaveFile);
void writeBlocks2(FILE * SaveFile);
void writeRegion2(FILE * SaveFile);
bool writeVersion2(FILE * SaveFile);
uint32_t regionX;
uint32_t regionY;
uint32_t regionZ;
///FIXME: these belong to some world structure
uint32_t worldSizeX;
uint32_t worldSizeY;
vector<uint16_t> v_geology[eBiomeCount];
vector<string> v_matgloss[NUM_MATGLOSS_TYPES];
vector<string> v_buildingtypes;
vector<t_construction> v_constructions;
vector<t_building*> v_buildings;
vector<t_tree_desc*> v_trees;
unsigned x_block_count, y_block_count, z_block_count; // block count
unsigned x_cell_count, y_cell_count, z_cell_count; // cell count
public:
DfMap();
DfMap(uint32_t x, uint32_t y, uint32_t z);
DfMap(string file_name);
~DfMap();
/// TODO: rework matgloss
void applyGeoMatgloss(Block * b);
// accessing vectors of materials
uint16_t getNumMatGloss(uint16_t type);
string getMaterialTypeString (uint32_t type);
string getMatGlossString(uint16_t type, uint16_t index);
// accessing vectors of building types
uint32_t getNumBuildingTypes();
string getBuildingTypeName(uint32_t index);
bool isValid();
bool load(string FilePath);
bool write(string FilePath);
void clear();
Block* getBlock(uint32_t x, uint32_t y, uint32_t z);
Block* allocBlock(uint32_t x, uint32_t y, uint32_t z);
bool deallocBlock(uint32_t x, uint32_t y, uint32_t z);
vector<t_building *> * getBlockBuildingsVector(uint32_t x,uint32_t y,uint32_t z);
vector<t_tree_desc *> * getBlockVegetationVector(uint32_t x,uint32_t y,uint32_t z);
inline unsigned int getXBlocks() { return x_block_count; }
inline unsigned int getYBlocks() { return y_block_count; }
inline unsigned int getZBlocks() { return z_block_count; }
bool isTileSky(uint32_t x, uint32_t y, uint32_t z, uint32_t blockX, uint32_t blockY);
uint16_t getTileType(uint32_t x, uint32_t y, uint32_t z);
uint16_t getTileType(uint32_t x, uint32_t y, uint32_t z, uint32_t blockX, uint32_t blockY);
uint32_t getDesignations(uint32_t x, uint32_t y, uint32_t z);
uint32_t getOccupancies(uint32_t x, uint32_t y, uint32_t z);
// get tile material
t_matglossPair getMaterialPair (uint32_t x, uint32_t y, uint32_t z);
string getGeoMaterialString (uint32_t x, uint32_t y, uint32_t z);
string getMaterialString (uint32_t type, uint32_t index);
// get coords of region used for materials
void getGeoRegion (uint32_t x, uint32_t y, uint32_t z, int32_t& geoX, int32_t& geoY);
// matgloss part of the designation
uint32_t getGeolayerIndex (uint32_t x, uint32_t y, uint32_t z);
void getRegionCoords (uint32_t &x,uint32_t &y,uint32_t &z);
void setRegionCoords (uint32_t x,uint32_t y,uint32_t z);
// what kind of building is here?
//uint16_t getBuilding (uint32_t x, uint32_t y, uint32_t z);
t_building *getBuilding (uint32_t x, uint32_t y, uint32_t z);
t_tree_desc *getTree (uint32_t x, uint32_t y, uint32_t z);
unsigned int getBiome (uint32_t x, uint32_t y, uint32_t z);
int picktexture(int);
/*
bool isOpenTerrain(int);
bool isStairTerrain(int);
bool isRampTerrain(int);
bool isFloorTerrain(int);
bool isWallTerrain(int);
*/
bool isBlockInitialized(uint32_t x, uint32_t y, uint32_t z);
bool isHidden (uint32_t x, uint32_t y, uint32_t z);
bool isSubterranean (uint32_t x, uint32_t y, uint32_t z);
bool isSkyView (uint32_t x, uint32_t y, uint32_t z);
bool isSunLit (uint32_t x, uint32_t y, uint32_t z);
bool isMagma (uint32_t x, uint32_t y, uint32_t z);
uint8_t getLiquidLevel(uint32_t x, uint32_t y, uint32_t z);
};
#endif // DFMAP_H_INCLUDED

@ -1,41 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef DF_MAP_HEADER_H
#define DF_MAP_HEADER_H
static const char dmh_id[] = "!!URIST!!";
static const uint8_t dmh_ver = 1U;
// a header for save files
struct DfMapHeader
{
char identifier[10]; // !!URIST!!
uint8_t version; // DfMap/Header version; current: 1
uint32_t reserved; // reserved 4 bytes
};
#endif // DF_MAP_HEADER_H

@ -1,433 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
// Extractor
#include "DFCommon.h"
using namespace std;
#include "Extract.h"
#include "DFDataModel.h"
#include "DFMemInfo.h"
Extractor::Extractor()
{
df_map = NULL; // important, null pointer means we don't have a map loaded
}
Extractor::~Extractor()
{
if(df_map !=NULL )
{
delete df_map;
}
}
bool Extractor::dumpMemory( string path_to_xml)
{
// create process manager, get first process
ProcessManager pm(path_to_xml);
if(!pm.findProcessess())
{
fprintf(stderr,"Can't find any suitable DF process\n");
return false;
}
// attach to process
printf("Attempting to Attach Process\n");
///FIXME: this won't do.
Process * p = pm[0];
DataModel * dm = p->getDataModel();
if(!p->attach())
{
printf("Could not Attach Process, Aborting\n");
return false; // couldn't attach to process, no go
}
printf("Process succesfully Attached\n");
memory_info* offset_descriptor = p->getDescriptor();
uint32_t map_loc, // location of the X array
temp_loc, // block location
temp_locx, // iterator for the X array
temp_locy, // iterator for the Y array
temp_locz; // iterator for the Z array
unsigned blocks_read = 0U;
// Read Map Data Blocks
int map_offset = offset_descriptor->getAddress("map_data");;
int x_count_offset = offset_descriptor->getAddress("x_count");
int y_count_offset = offset_descriptor->getAddress("y_count");
int z_count_offset = offset_descriptor->getAddress("z_count");
int tile_type_offset = offset_descriptor->getOffset("type");
int designation_offset = offset_descriptor->getOffset("designation");
int occupancy_offset = offset_descriptor->getOffset("occupancy");
int biome_stuffs = offset_descriptor->getOffset("biome_stuffs");
// layers
int region_x_offset = offset_descriptor->getAddress("region_x");
int region_y_offset = offset_descriptor->getAddress("region_y");
int region_z_offset = offset_descriptor->getAddress("region_z");
int world_offset = offset_descriptor->getAddress("world");
int world_regions_offset = offset_descriptor->getOffset("w_regions_arr");
int region_size = offset_descriptor->getHexValue("region_size");
int region_geo_index_offset = offset_descriptor->getOffset("region_geo_index_off");
int world_geoblocks_offset = offset_descriptor->getOffset("w_geoblocks");
int world_size_x = offset_descriptor->getOffset("world_size_x");
int world_size_y = offset_descriptor->getOffset("world_size_y");
int geolayer_geoblock_offset = offset_descriptor->getOffset("geolayer_geoblock_offset");
// veins
int veinvector = offset_descriptor->getOffset("v_vein");
int veinsize = offset_descriptor->getHexValue("v_vein_size");
int vegetation = offset_descriptor->getAddress("vegetation");
int tree_desc_offset = offset_descriptor->getOffset("tree_desc_offset");
// constructions
int constructions = offset_descriptor->getAddress("constructions");
// buildings
int buildings = offset_descriptor->getAddress("buildings");
/// TODO: what about building shape and orientation?
// matgloss
int matgloss_address = offset_descriptor->getAddress("matgloss");
int matgloss_skip = offset_descriptor->getHexValue("matgloss_skip");
bool have_geology = false;
printf("Map offset: 0x%.8X\n", map_offset);
map_loc = MreadDWord(map_offset);
if (!map_loc)
{
printf("Could not find DF map information in memory, Aborting\n");
return false;
}
printf("Map data Found at: 0x%.8X\n", map_loc);
if(df_map != NULL)
{
delete df_map;
}
df_map = new DfMap(MreadDWord(x_count_offset),MreadDWord(y_count_offset),MreadByte(z_count_offset));
// read matgloss data from df if we can
RawType matglossRawMapping[] = {Mat_Wood, Mat_Stone, Mat_Metal, Mat_Plant};
if(matgloss_address && matgloss_skip)
{
uint32_t addr = matgloss_address;
uint32_t counter = Mat_Wood;
for(; counter < NUM_MATGLOSS_TYPES; addr += matgloss_skip, counter++)
{
// get vector of matgloss pointers
DfVector p_matgloss = dm->readVector(addr, 4);
// iterate over it
for (uint32_t i = 0; i< p_matgloss.getSize();i++)
{
uint32_t temp;
string tmpstr;
// read the matgloss pointer from the vector into temp
p_matgloss.read((uint32_t)i,(uint8_t *)&temp);
// read the string pointed at by temp
tmpstr = dm->readSTLString(temp);
// store it in the block
df_map->v_matgloss[matglossRawMapping[counter]].push_back(tmpstr);
printf("%d = %s\n",i,tmpstr.c_str());
}
}
}
if(region_x_offset && region_y_offset && region_z_offset)
{
// we have offsets for region coordinates, get them.
df_map->setRegionCoords(MreadDWord(region_x_offset),MreadDWord(region_y_offset),MreadDWord(region_z_offset));
// extract layer geology data. we need all these to do that
if(world_size_x && world_size_y && world_offset && world_regions_offset && world_geoblocks_offset && region_size && region_geo_index_offset && geolayer_geoblock_offset)
{
// get world size
int worldSizeX = MreadWord(world_offset + world_size_x);
int worldSizeY = MreadWord(world_offset + world_size_y);
df_map->worldSizeX = worldSizeX;
df_map->worldSizeY = worldSizeY;
printf("World size. X=%d Y=%d\n",worldSizeX,worldSizeY);
// get pointer to first part of 2d array of regions
uint32_t regions = MreadDWord(world_offset + world_regions_offset);
printf("regions. Offset=%d\n",regions);
// read the 9 surrounding regions
DfVector geoblocks = dm->readVector(world_offset + world_geoblocks_offset,4);
// iterate over surrounding biomes. make sure we don't fall off the world
for(int i = eNorthWest; i< eBiomeCount; i++)
{
// check bounds, fix them if needed
int bioRX = df_map->regionX / 16 + (i%3) - 1;
if( bioRX < 0) bioRX = 0;
if( bioRX >= worldSizeX) bioRX = worldSizeX - 1;
int bioRY = df_map->regionY / 16 + (i/3) - 1;
if( bioRY < 0) bioRY = 0;
if( bioRY >= worldSizeY) bioRY = worldSizeY - 1;
/// TODO: encapsulate access to multidimensional arrays.
// load region stuff here
uint32_t geoX = MreadDWord(regions + bioRX*4);// get pointer to column of regions
// geoX = base
// bioRY = index
// region_size = size of array objects
// region_geo_index_off = offset into the array object
uint16_t geoindex = MreadWord(geoX + bioRY*region_size + region_geo_index_offset);
uint32_t geoblock_off;
// get the geoblock from the geoblock vector using the geoindex
geoblocks.read(geoindex,(uint8_t *) &geoblock_off);
// get the layer pointer vector :D
DfVector geolayers = dm->readVector(geoblock_off + geolayer_geoblock_offset , 4); // let's hope
// make sure we don't load crap
assert(geolayers.getSize() > 0 && geolayers.getSize() <= 16);
for(uint32_t j = 0;j< geolayers.getSize();j++)
{
int geol_offset;
// read pointer to a layer
geolayers.read(j, (uint8_t *) & geol_offset);
// read word at pointer + 2, store in our geology vectors
df_map->v_geology[i].push_back(MreadWord(geol_offset + 2));
}
}
have_geology = true;
}
}
else
{
// crap, can't get the real layer materials
df_map->setRegionCoords(0,0,0);
}
//read the memory from the map blocks
for(uint32_t x = 0; x < df_map->x_block_count; x++)
{
temp_locx = map_loc + ( 4 * x );
temp_locy = MreadDWord(temp_locx);
for(uint32_t y = 0; y < df_map->y_block_count; y++)
{
temp_locz = MreadDWord(temp_locy);
temp_locy += 4;
for(uint32_t z = 0; z < df_map->z_block_count; z++)
{
temp_loc = MreadDWord(temp_locz);
temp_locz += 4;
if (temp_loc)
{
Block * b = df_map->allocBlock(x,y,z);
b->origin = temp_loc; // save place of block in DF's memory for later
Mread(
/*Uint32 offset*/ temp_loc + tile_type_offset,
/*Uint32 size*/ sizeof(uint16_t)*BLOCK_SIZE*BLOCK_SIZE,
/*void *target*/ (uint8_t *)&b->tile_type
);
Mread(
/*Uint32 offset*/ temp_loc + designation_offset,
/*Uint32 size*/ sizeof(uint32_t)*BLOCK_SIZE*BLOCK_SIZE,
/*void *target*/ (uint8_t *)&b->designation
);
Mread(
/*Uint32 offset*/ temp_loc + occupancy_offset,
/*Uint32 size*/ sizeof(uint32_t)*BLOCK_SIZE*BLOCK_SIZE,
/*void *target*/ (uint8_t *)&b->occupancy
);
// set all materials to -1.
memset(b->material, -1, sizeof(int16_t) * 256);
if(biome_stuffs) // we got biome stuffs! we can try loading matgloss from here
{
Mread(
/*Uint32 offset*/ temp_loc + biome_stuffs,
/*Uint32 size*/ sizeof(uint8_t)*16,
/*void *target*/ (uint8_t *)&b->RegionOffsets
);
// if we have geology, we can use the geolayers to determine materials
if(have_geology)
{
df_map->applyGeoMatgloss(b);
}
}
else
{
// can't load offsets, substitute local biome everywhere
memset(b->RegionOffsets,eHere,sizeof(b->RegionOffsets));
}
// load veins from the game
if(veinvector && veinsize)
{
assert(sizeof(t_vein) == veinsize);
// veins are stored as a vector of pointers to veins .. at least in df 40d11 on linux
/*pointer is 4 bytes! we work with a 32bit program here, no matter what architecture we compile khazad for*/
DfVector p_veins = dm->readVector(temp_loc + veinvector, 4);
// read all veins
for (uint32_t i = 0; i< p_veins.getSize();i++)
{
t_vein v;
uint32_t temp;
// read the vein pointer from the vector
p_veins.read((uint32_t)i,(uint8_t *)&temp);
// read the vein data (dereference pointer)
Mread(temp, veinsize, (uint8_t *)&v);
// store it in the block
b->veins.push_back(v);
}
b->collapseVeins(); // collapse *our* vein vector into vein matgloss data
}
}
}
}
}
// read constructions, apply immediately.
if(constructions)
{
// read the constructions vector
DfVector p_cons = dm->readVector(constructions,4);
// iterate
for (uint32_t i = 0; i< p_cons.getSize();i++)
{
uint32_t temp;
t_construction c;
t_construction_df40d c_40d;
// read pointer from vector at position
p_cons.read((uint32_t)i,(uint8_t *)&temp);
//read construction from memory
Mread(temp, sizeof(t_construction_df40d), (uint8_t *)&c_40d);
// stupid apply. this will probably be removed later
Block * b = df_map->getBlock(c_40d.x/16,c_40d.y/16,c_40d.z);
b->material[c_40d.x%16][c_40d.y%16] = c_40d.material;
//b->material[c_40d.x%16][c_40d.y%16].index = c_40d.material.index;
// transform
c.x = c_40d.x;
c.y = c_40d.y;
c.z = c_40d.z;
c.material = c_40d.material;
// store for save/load
df_map->v_constructions.push_back(c);
}
}
if(buildings)
{
// fill the building type vector first
offset_descriptor->copyBuildings(df_map->v_buildingtypes);
DfVector p_bld = dm->readVector(buildings,4);
for (uint32_t i = 0; i< p_bld.getSize();i++)
{
uint32_t temp;
t_building * bld = new t_building;
t_building_df40d bld_40d;
// read pointer from vector at position
p_bld.read((uint32_t)i,(uint8_t *)&temp);
//read construction from memory
Mread(temp, sizeof(t_building_df40d), (uint8_t *)&bld_40d);
// transform
int32_t type = -1;
offset_descriptor->resolveClassId(temp, type);
bld->vtable = bld_40d.vtable;
bld->type = type;
bld->x1 = bld_40d.x1;
bld->x2 = bld_40d.x2;
bld->y1 = bld_40d.y1;
bld->y2 = bld_40d.y2;
bld->z = bld_40d.z;
bld->material = bld_40d.material;
// store for save/load. will need more processing.
df_map->v_buildings.push_back(bld);
///FIXME: delete created building structs
// save buildings in a block for later display
Block * b = df_map->getBlock(bld->x1/16,bld->y1/16,bld->z);
b->v_buildings.push_back(bld);
}
}
if(vegetation && tree_desc_offset)
{
DfVector p_tree = dm->readVector(vegetation,4);
for (uint32_t i = 0; i< p_tree.getSize();i++)
{
uint32_t temp;
t_tree_desc * tree = new t_tree_desc;
// read pointer from vector at position
p_tree.read((uint32_t)i,(uint8_t *)&temp);
//read construction from memory
Mread(temp + tree_desc_offset, sizeof(t_tree_desc), (uint8_t *)tree);
// fix bad stuff
if(tree->material.type == 2) tree->material.type = 3;
// store for save/load. will need more processing.
df_map->v_trees.push_back(tree);
// save buildings in a block for later display
Block * b = df_map->getBlock(tree->x/16,tree->y/16,tree->z);
b->v_trees.push_back(tree);
}
}
printf("Blocks read into memory: %d\n", blocks_read);
p->detach();
return true;
}
// wrappers!
bool Extractor::loadMap(string FileName)
{
if(df_map == NULL)
{
df_map = new DfMap(FileName);
}
else
{
df_map->load(FileName);
}
return df_map->isValid();
}
bool Extractor::writeMap(string FileName)
{
if(df_map == NULL)
{
return false;
}
return df_map->write(FileName);
}
bool Extractor::isMapLoaded()
{
if(df_map != NULL)
{
if(df_map->isValid())
{
return true;
}
}
return false;
}

@ -1,51 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/* Memory research
http://dwarffortresswiki.net/index.php/User:Rick/memory.ini#A_table_of_available_settings
http://dwarffortresswiki.net/index.php/User:Rick/Memory_research#Tile_Block
http://dwarffortresswiki.net/index.php/User:AzureLightning/Memory_research
http://dwarffortresswiki.net/index.php/User:Iluxan/Memory_research
*/
#ifndef EXTRACT_HEADER
#define EXTRACT_HEADER
class DfMap;
class Extractor
{
protected:
DfMap *df_map; // DF extracted map structure
public:
bool Init();
Extractor();
~Extractor();
bool loadMap(string FileName);
bool writeMap(string FileName);
bool isMapLoaded();
DfMap *getMap() {return df_map;};
bool dumpMemory( string path_to_xml);
};
#endif // EXTRACT_HEADER

@ -1,188 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "DFCommon.h"
#include "DfMap.h"
#include "DfMapHeader.h"
#include "ZlibHelper.h"
bool DfMap::write(string FilePath)
{
FILE *SaveFile;
SaveFile = fopen(FilePath.c_str(),"wb");
DfMapHeader df_map_header;
if(SaveFile == NULL)
{
printf("Can\'t create file for write.\n");
return false;
}
else
{
// gather information to fill dfmapheader
strcpy(df_map_header.identifier, dmh_id);
df_map_header.version = dmh_ver;
df_map_header.reserved = 0/*sizeof(DfMapHeader)*/;
// save map header
fwrite(&df_map_header, sizeof(DfMapHeader), 1, SaveFile);
// save map
writeVersion1(SaveFile);
}
// reopen file for reading
freopen (FilePath.c_str(),"rb",SaveFile);
if(SaveFile == NULL)
{
printf("Can\'t create file for read.\n");
return false;
}
FILE *SaveCompressedFile;
string CompressedFilePath = FilePath + ".comp";
SaveCompressedFile = fopen(CompressedFilePath.c_str(),"wb");
if(SaveCompressedFile == NULL)
{
printf("Can\'t create a compressed file for write\n");
return false;
}
// compress
printf("Compressing... ");
int ret = def(SaveFile, SaveCompressedFile, Z_BEST_COMPRESSION);
if (ret != Z_OK)
{
zerr(ret);
}
printf("DONE\n");
fclose(SaveFile);
fclose(SaveCompressedFile);
remove(FilePath.c_str());
rename(CompressedFilePath.c_str(), FilePath.c_str());
return true;
}
bool DfMap::load(string FilePath)
{
string DecompressedFilePath = FilePath + ".decomp";
FILE *ToDecompress;
FILE *Decompressed;
DfMapHeader df_map_header;
bool isok = false;
// open file for writing decompressed data
Decompressed = fopen(DecompressedFilePath.c_str(), "wb");
if (Decompressed == NULL)
{
printf("Can\'t open a decompressed file for write.\n");
return false;
}
// open compressed file
ToDecompress = fopen(FilePath.c_str(),"rb");
if (ToDecompress == NULL)
{
printf("Can\'t open file for read.\n");
return false;
}
// decompress
printf("Decompressing... ");
int ret = inf(/*source*/ToDecompress,/*destination*/Decompressed);
printf("DONE\n");
if (ret != Z_OK)
{
zerr(ret);
}
// OK, close file with compressed data
fclose(ToDecompress);
// reopen decompressed file for reading
freopen(DecompressedFilePath.c_str(), "rb", Decompressed);
if (Decompressed == NULL)
{
printf("Can\'t create decompressed file for read.\n");
return false;
}
// check, if the file is big enough to contain the header
fseek(Decompressed, 0, SEEK_END);
if (ftell(Decompressed) < (int32_t)sizeof(DfMapHeader))
{
printf("This Khazad map file is corrupted - file too small.\n");
return false;
}
// read the header
fseek(Decompressed, 0, SEEK_SET);
fread(&df_map_header, sizeof(DfMapHeader), 1, Decompressed);
// check, if it's a Khazad map file
if (strcmp(df_map_header.identifier,dmh_id) != 0)
{
printf("This file is not a Khazad map file.\n");
return false;
}
// ALERT: flush all map data. This is very important.
clear();
switch(df_map_header.version)
{
/*
Basic format without matgloss. Kept for compatibility reasons.
Saved from version 0.0.5
*/
case 1:
isok = loadVersion1(Decompressed, df_map_header);
break;
/*
v2 format
Saved from some SVN version. this format is dead
*/
case 2:
//isok = loadVersion2(Decompressed, df_map_header);
isok = false;
break;
default:
printf("Unknown Khazad map file version(%3d).\n", df_map_header.version);
isok = false;
break;
}
// close decompressed file and delete it
fclose(Decompressed);
remove(DecompressedFilePath.c_str());
return isok;
}

@ -1,106 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "DFCommon.h"
#include "DfMap.h"
#include "DfMapHeader.h"
#include "ZlibHelper.h"
// LOAD v1 BLOCKS
bool DfMap::loadVersion1(FILE * Decompressed,DfMapHeader & h)
{
uint32_t x, y, z;
uint32_t tile_block_count; // how many tile blocks to read from the data location
// load new size information
fread(&tile_block_count, sizeof(uint32_t), 1, Decompressed);
fread(&x_block_count, sizeof(uint32_t), 1, Decompressed);
fread(&y_block_count, sizeof(uint32_t), 1, Decompressed);
fread(&z_block_count, sizeof(uint32_t), 1, Decompressed);
// make sure those size variables are in sync
updateCellCount();
// alloc new space for our new size
allocBlockArray(x_block_count,y_block_count,z_block_count);
// let's load the blocks
for (uint32_t tile_block = 0U; tile_block < tile_block_count; ++tile_block)
{
// block position - we can omit empty blocks this way
fread(&x, sizeof(uint32_t), 1, Decompressed);
fread(&y, sizeof(uint32_t), 1, Decompressed);
fread(&z, sizeof(uint32_t), 1, Decompressed);
Block * b = allocBlock(x,y,z);
// read data
fread(&b->tile_type, sizeof(b->tile_type), 1, Decompressed);
fread(&b->designation, sizeof(b->designation), 1, Decompressed);
fread(&b->occupancy, sizeof(b->occupancy), 1, Decompressed);
memset(b->material, -1, sizeof(b->material));
// can't load offsets, substitute local biome everywhere
memset(b->RegionOffsets,eHere,sizeof(b->RegionOffsets));
}
printf("Blocks read into memory: %d\n", tile_block_count);
return true;
}
// SAVE v1 BLOCKS
bool DfMap::writeVersion1(FILE * SaveFile)
{
uint32_t x, y, z;
// write size information - total blocks and map size
fwrite(&blocks_allocated, sizeof(uint32_t), 1, SaveFile);
fwrite(&x_block_count, sizeof(uint32_t), 1, SaveFile);
fwrite(&y_block_count, sizeof(uint32_t), 1, SaveFile);
fwrite(&z_block_count, sizeof(uint32_t), 1, SaveFile);
// write each non-empty block
for (x = 0; x < x_block_count; x++ )
{
for (y = 0; y < y_block_count; y++ )
{
for (z = 0; z < z_block_count; z++ )
{
Block *b = getBlock(x,y,z);
if(b != NULL)
{
// first goes block position
fwrite(&x, sizeof(uint32_t), 1, SaveFile);
fwrite(&y, sizeof(uint32_t), 1, SaveFile);
fwrite(&z, sizeof(uint32_t), 1, SaveFile);
// then block data
fwrite(&b->tile_type, sizeof(uint16_t), BLOCK_SIZE*BLOCK_SIZE, SaveFile);
fwrite(&b->designation, sizeof(uint32_t), BLOCK_SIZE*BLOCK_SIZE, SaveFile);
fwrite(&b->occupancy, sizeof(uint32_t), BLOCK_SIZE*BLOCK_SIZE, SaveFile);
}
}
}
}
return true;
}

@ -1,196 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "DFCommon.h"
#include "DfMap.h"
#include "DfMapHeader.h"
#include "ZlibHelper.h"
/*
bool DfMap::loadMatgloss2(FILE * Decompressed)
{
char buffer [256];
uint32_t nummatgloss;
uint32_t temp;
fread(&nummatgloss, sizeof(uint32_t), 1, Decompressed);
///FIXME: buffer overrun possible? probably not. but fix it anyway.
for(uint32_t i = 0; i< nummatgloss;i++)
{
fread(&temp, sizeof(uint32_t), 1, Decompressed); // string length
fread(&buffer, sizeof(char), temp, Decompressed); // string
buffer[temp] = 0;
v_matgloss[Mat_Stone].push_back(buffer);
}
}
bool DfMap::loadBlocks2(FILE * Decompressed,DfMapHeader & h)
{
uint32_t x, y, z;
uint32_t numveins;
t_vein vein;
// for (uint32_t tile_block = 0U; tile_block < h.tile_block_count; ++tile_block)
{
fread(&x, sizeof(uint32_t), 1, Decompressed);
fread(&y, sizeof(uint32_t), 1, Decompressed);
fread(&z, sizeof(uint32_t), 1, Decompressed);
Block * b = allocBlock(x,y,z);
fread(&b->tile_type, sizeof(b->tile_type), 1, Decompressed);
fread(&b->designation, sizeof(b->designation), 1, Decompressed);
fread(&b->occupancy, sizeof(b->occupancy), 1, Decompressed);
fread(&b->RegionOffsets,sizeof(b->RegionOffsets),1,Decompressed);
// load all veins of this block
fread(&numveins, sizeof(uint32_t), 1, Decompressed);
if(v_matgloss[Mat_Stone].size())
{
applyGeoMatgloss(b);
}
for(uint32_t i = 0; i < numveins; i++)
{
fread(&vein,sizeof(t_vein),1,Decompressed);
b->veins.push_back(vein);
}
if(numveins)
b->collapseVeins();
}
}
bool DfMap::loadRegion2(FILE * Decompressed)
{
uint32_t temp, temp2;
for(uint32_t i = eNorthWest; i< eBiomeCount;i++)
{
fread(&temp, sizeof(uint32_t), 1, Decompressed); // layer vector length
for(uint32_t j = 0; j < temp;j++) // load all geolayers into vectors (just 16bit matgloss indices)
{
fread(&temp2, sizeof(uint16_t), 1, Decompressed);
v_geology[i].push_back(temp2);
}
}
}
bool DfMap::loadVersion2(FILE * Decompressed,DfMapHeader & h)
{
return false;
uint32_t tile_block_count; // how many tile blocks to read from the data location
//uint32_t x_block_count, y_block_count, z_block_count; // DF's map block count
fread(&tile_block_count, sizeof(uint32_t), 1, Decompressed);
fread(&x_block_count, sizeof(uint32_t), 1, Decompressed);
fread(&y_block_count, sizeof(uint32_t), 1, Decompressed);
fread(&z_block_count, sizeof(uint32_t), 1, Decompressed);
// load new size information
//x_block_count = h.x_block_count;
//y_block_count = h.y_block_count;
//z_block_count = h.z_block_count;
// make sure those size variables are in sync
updateCellCount();
// alloc new space for our new size
allocBlockArray(x_block_count,y_block_count,z_block_count);
// fseek(Decompressed, h.map_data_location, SEEK_SET);
// read matgloss vector
loadMatgloss2(Decompressed);
// read region data
loadRegion2(Decompressed);
// read blocks
loadBlocks2(Decompressed,h);
return true;
}
void DfMap::writeMatgloss2(FILE * SaveFile)
{
uint32_t nummatgloss = v_matgloss[Mat_Stone].size();
fwrite(&nummatgloss, sizeof(uint32_t), 1, SaveFile);
for(uint32_t i = 0; i< nummatgloss;i++)
{
const char *saveme = v_matgloss[Mat_Stone][i].c_str();
uint32_t length = v_matgloss[Mat_Stone][i].size();
fwrite(&length, sizeof(uint32_t),1,SaveFile);
fwrite(saveme, sizeof(char), length, SaveFile);
}
}
void DfMap::writeRegion2(FILE * SaveFile)
{
uint32_t temp, temp2;
for(uint32_t i = eNorthWest; i< eBiomeCount;i++)
{
temp = v_geology[i].size();
fwrite(&temp, sizeof(uint32_t), 1, SaveFile); // layer vector length
for(uint32_t j = 0; j < temp;j++) // write all geolayers (just 16bit matgloss indices)
{
temp2 = v_geology[i][j];
fwrite(&temp2, sizeof(uint16_t), 1, SaveFile);
}
}
}
void DfMap::writeBlocks2(FILE * SaveFile)
{
uint32_t x, y, z, numveins;
for (x = 0; x < x_block_count; x++ )
{
for (y = 0; y < y_block_count; y++ )
{
for (z = 0; z < z_block_count; z++ )
{
Block *b = getBlock(x,y,z);
if(b != NULL)
{
// which block it is
fwrite(&x, sizeof(uint32_t), 1, SaveFile);
fwrite(&y, sizeof(uint32_t), 1, SaveFile);
fwrite(&z, sizeof(uint32_t), 1, SaveFile);
// block data
fwrite(&b->tile_type, sizeof(uint16_t), BLOCK_SIZE*BLOCK_SIZE, SaveFile);
fwrite(&b->designation, sizeof(uint32_t), BLOCK_SIZE*BLOCK_SIZE, SaveFile);
fwrite(&b->occupancy, sizeof(uint32_t), BLOCK_SIZE*BLOCK_SIZE, SaveFile);
fwrite(&b->RegionOffsets, sizeof(b->RegionOffsets), 1, SaveFile);
// write all veins
numveins = b->veins.size();
fwrite(&numveins, sizeof(uint32_t), 1, SaveFile);
for(uint32_t i = 0; i < numveins; i++)
{
fwrite(&b->veins[i],sizeof(t_vein),1,SaveFile);
}
}
}
}
}
}
bool DfMap::writeVersion2(FILE * SaveFile)
{
// write matgloss vector
writeMatgloss2(SaveFile);
// write region data
writeRegion2(SaveFile);
// write blocks
writeBlocks2(SaveFile);
return true;
}
*/

@ -1,160 +0,0 @@
// SOURCE: http://www.zlib.net/zpipe.c
#ifndef ZLIB_HELPER_HEADER
#define ZLIB_HELPER_HEADER
#include <zlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
//#define CHUNK 16384
#define CHUNK 262144
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
inline int def(FILE *source, FILE *dest, int level)
{
int ret, flush;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return ret;
/* compress until end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
/* done when last data in file processed */
} while (flush != Z_FINISH);
assert(ret == Z_STREAM_END); /* stream will be complete */
/* clean up and return */
(void)deflateEnd(&strm);
return Z_OK;
}
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
inline int inf(FILE *source, FILE *dest)
{
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
/* decompress until deflate stream ends or end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
/* report a zlib or i/o error */
inline void zerr(int ret)
{
printf("zpipe: %d\n", ret);
switch (ret) {
case Z_ERRNO:
if (ferror(stdin))
fprintf(stderr,"error reading stdin\n");
if (ferror(stdout))
fprintf(stderr,"error writing stdout\n");
break;
case Z_STREAM_ERROR:
printf("invalid compression level\n");
break;
case Z_DATA_ERROR:
printf("invalid or incomplete deflate data\n");
break;
case Z_MEM_ERROR:
printf("out of memory\n");
break;
case Z_VERSION_ERROR:
printf("zlib version mismatch!\n");
}
}
#endif // ZLIB_HELPER_HEADER