Maps no longer copy the map block pointer array, blocks are structs, map data is public.

develop
Petr Mrázek 2011-07-07 07:00:36 +02:00
parent 4cd80fa5d4
commit 4ff5db06be
8 changed files with 222 additions and 321 deletions

@ -79,9 +79,10 @@ Process::Process(VersionInfoFactory * known_versions)
} }
} }
string Process::doReadClassName (uint32_t vptr) string Process::doReadClassName (void * vptr)
{ {
int typeinfo = Process::readDWord(vptr - 0x4); //FIXME: BAD!!!!!
int typeinfo = Process::readDWord((uint32_t)vptr - 0x4);
int typestring = Process::readDWord(typeinfo + 0x4); int typestring = Process::readDWord(typeinfo + 0x4);
string raw = readCString(typestring); string raw = readCString(typestring);
size_t start = raw.find_first_of("abcdefghijklmnopqrstuvwxyz");// trim numbers size_t start = raw.find_first_of("abcdefghijklmnopqrstuvwxyz");// trim numbers

@ -973,7 +973,7 @@ void VersionInfo::setClassChild (t_class * parent, const char * name, const char
} }
// FIXME: stupid. we need a better container // FIXME: This in now DEPRECATED!
bool VersionInfo::resolveObjectToClassID(const uint32_t address, int32_t & classid) bool VersionInfo::resolveObjectToClassID(const uint32_t address, int32_t & classid)
{ {
uint32_t vtable = d->p->readDWord(address); uint32_t vtable = d->p->readDWord(address);
@ -990,7 +990,8 @@ bool VersionInfo::resolveObjectToClassID(const uint32_t address, int32_t & class
else// couldn't find? else// couldn't find?
{ {
// we set up the class for the first time // we set up the class for the first time
string classname = d->p->readClassName(vtable); //FIXME: use actual pointers everywhere.
string classname = d->p->readClassName((void*)vtable);
d->classIDs[vtable] = cl = setClass(classname.c_str(),vtable); d->classIDs[vtable] = cl = setClass(classname.c_str(),vtable);
} }
// and isn't a multi-class // and isn't a multi-class
@ -1027,7 +1028,7 @@ bool VersionInfo::resolveObjectToClassID(const uint32_t address, int32_t & class
//ALERT: doesn't care about multiclasses //ALERT: doesn't care about multiclasses
bool VersionInfo::resolveClassnameToVPtr(const string classname, uint32_t & vptr) bool VersionInfo::resolveClassnameToVPtr(const string classname, void * & vptr)
{ {
// FIXME: another stupid search. // FIXME: another stupid search.
for(uint32_t i = 0;i< d->classes.size();i++) for(uint32_t i = 0;i< d->classes.size();i++)
@ -1035,7 +1036,7 @@ bool VersionInfo::resolveClassnameToVPtr(const string classname, uint32_t & vptr
//if(classes[i].) //if(classes[i].)
if(d->classes[i]->classname == classname) // got class if(d->classes[i]->classname == classname) // got class
{ {
vptr = d->classes[i]->vtable; vptr = (void *) d->classes[i]->vtable;
return true; return true;
} }
} }

@ -228,11 +228,11 @@ namespace DFHack
} }
/// get class name of an object with rtti/type info /// get class name of an object with rtti/type info
std::string doReadClassName(uint32_t vptr); std::string doReadClassName(void * vptr);
std::string readClassName(uint32_t vptr) std::string readClassName(void * vptr)
{ {
std::map<uint32_t, std::string>::iterator it = classNameCache.find(vptr); std::map<void *, std::string>::iterator it = classNameCache.find(vptr);
if (it != classNameCache.end()) if (it != classNameCache.end())
return it->second; return it->second;
return classNameCache[vptr] = doReadClassName(vptr); return classNameCache[vptr] = doReadClassName(vptr);
@ -274,13 +274,13 @@ namespace DFHack
bool identified; bool identified;
uint32_t my_pid; uint32_t my_pid;
uint32_t base; uint32_t base;
std::map<uint32_t, std::string> classNameCache; std::map<void *, std::string> classNameCache;
}; };
class DFHACK_EXPORT ClassNameCheck class DFHACK_EXPORT ClassNameCheck
{ {
std::string name; std::string name;
mutable uint32_t vptr; mutable void * vptr;
public: public:
ClassNameCheck() : vptr(0) {}; ClassNameCheck() : vptr(0) {};
ClassNameCheck(std::string _name) : name(_name), vptr(0) {}; ClassNameCheck(std::string _name) : name(_name), vptr(0) {};
@ -288,7 +288,7 @@ namespace DFHack
{ {
name = b.name; vptr = b.vptr; return *this; name = b.name; vptr = b.vptr; return *this;
} }
bool operator() (Process *p, uint32_t ptr) const { bool operator() (Process *p, void * ptr) const {
if (vptr == 0 && p->readClassName(ptr) == name) if (vptr == 0 && p->readClassName(ptr) == name)
vptr = ptr; vptr = ptr;
return (vptr && vptr == ptr); return (vptr && vptr == ptr);

@ -183,7 +183,7 @@ namespace DFHack
* Get a vptr from a classname. Can fail if the type is not in the cache * Get a vptr from a classname. Can fail if the type is not in the cache
* limited to normal classes, variable-dependent types will resolve to the base class * limited to normal classes, variable-dependent types will resolve to the base class
*/ */
bool resolveClassnameToVPtr ( const std::string classname, uint32_t & vptr ); bool resolveClassnameToVPtr ( const std::string classname, void * & vptr );
/** /**
* Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID) * Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID)

@ -35,7 +35,7 @@ namespace MapExtras
void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & materials) void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & materials)
{ {
memset(materials,-1,sizeof(materials)); memset(materials,-1,sizeof(materials));
std::vector <DFHack::t_vein> veins; std::vector <DFHack::t_vein *> veins;
m->ReadVeins(bcoord.x,bcoord.y,bcoord.z,&veins); m->ReadVeins(bcoord.x,bcoord.y,bcoord.z,&veins);
//iterate through block rows //iterate through block rows
for(uint32_t j = 0;j<16;j++) for(uint32_t j = 0;j<16;j++)
@ -48,9 +48,9 @@ void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d &
{ {
for(int i = (int) veins.size() - 1; i >= 0;i--) for(int i = (int) veins.size() - 1; i >= 0;i--)
{ {
if(!!(((1 << k) & veins[i].assignment[j]) >> k)) if(!!(((1 << k) & veins[i]->assignment[j]) >> k))
{ {
materials[k][j] = veins[i].type; materials[k][j] = veins[i]->type;
i = -1; i = -1;
} }
} }

@ -145,34 +145,32 @@ namespace DFHack
uint32_t origin; uint32_t origin;
}; };
struct t_virtual
{
void * vptr;
};
/** /**
* mineral vein object - bitmap with a material type * mineral vein object - bitmap with a material type
* \ingroup grp_maps * \ingroup grp_maps
*/ */
struct t_vein struct t_vein : public t_virtual
{ {
uint32_t vtable;
/// index into the inorganic material vector /// index into the inorganic material vector
int32_t type; int32_t type;
/// bit mask describing how the vein maps to the map block /// bit mask describing how the vein maps to the map block
/// assignment[y] & (1 << x) describes the tile (x, y) of the block /// assignment[y] & (1 << x) describes the tile (x, y) of the block
int16_t assignment[16]; int16_t assignment[16];
uint32_t flags; uint32_t flags;
/// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
}; };
/** /**
* stores what tiles should appear when the ice melts - bitmap of material types * stores what tiles should appear when the ice melts - bitmap of material types
* \ingroup grp_maps * \ingroup grp_maps
*/ */
struct t_frozenliquidvein struct t_frozenliquidvein : public t_virtual
{ {
uint32_t vtable;
/// a 16x16 array of the original tile types /// a 16x16 array of the original tile types
int16_t tiles[16][16]; int16_t tiles[16][16];
/// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
}; };
/** /**
* \ingroup grp_maps * \ingroup grp_maps
@ -192,9 +190,8 @@ namespace DFHack
* \ingroup grp_maps * \ingroup grp_maps
* @see PrintSplatterType * @see PrintSplatterType
*/ */
struct t_spattervein struct t_spattervein : public t_virtual
{ {
uint32_t vtable;
/// generic material. /// generic material.
uint16_t mat1; uint16_t mat1;
/// possibly alignment artifact /// possibly alignment artifact
@ -208,37 +205,29 @@ namespace DFHack
uint16_t matter_state; uint16_t matter_state;
/// 16x16 array of covering 'intensity' /// 16x16 array of covering 'intensity'
uint8_t intensity[16][16]; uint8_t intensity[16][16];
/// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
}; };
/** /**
* a 'grass vein' defines the grass coverage of a map block * a 'grass vein' defines the grass coverage of a map block
* bitmap of density (max = 100) with plant material type * bitmap of density (max = 100) with plant material type
* \ingroup grp_maps * \ingroup grp_maps
*/ */
struct t_grassvein struct t_grassvein : public t_virtual
{ {
uint32_t vtable;
/// material vector index /// material vector index
uint32_t material; uint32_t material;
/// 16x16 array of covering 'intensity' /// 16x16 array of covering 'intensity'
uint8_t intensity[16][16]; uint8_t intensity[16][16];
/// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
}; };
/** /**
* defines the world constructions present. The material member is a mystery. * defines the world constructions present. The material member is a mystery.
* \ingroup grp_maps * \ingroup grp_maps
*/ */
struct t_worldconstruction struct t_worldconstruction : public t_virtual
{ {
uint32_t vtable;
/// material vector index /// material vector index
uint32_t material; uint32_t material;
/// 16x16 array of bits /// 16x16 array of bits
uint16_t assignment[16]; uint16_t assignment[16];
/// this is NOT part of the structure, but an address of it as seen by DFhack.
uint32_t address_of;
}; };
/** /**
@ -452,6 +441,7 @@ namespace DFHack
/// rest of the flags is completely unknown /// rest of the flags is completely unknown
unsigned int unk_2: 28; unsigned int unk_2: 28;
// there's a possibility that this flags field is shorter than 32 bits // there's a possibility that this flags field is shorter than 32 bits
// FIXME: yes, it's a crazy dynamically sized array of flags. DERP.
}; };
/** /**
@ -488,7 +478,7 @@ namespace DFHack
* array of 16 biome indexes valid for the block * array of 16 biome indexes valid for the block
* \ingroup grp_maps * \ingroup grp_maps
*/ */
typedef uint8_t biome_indices40d [16]; typedef uint8_t biome_indices40d [9];
/** /**
* 16x16 array of temperatures * 16x16 array of temperatures
* \ingroup grp_maps * \ingroup grp_maps
@ -527,7 +517,7 @@ namespace DFHack
unsigned char * flagarray; unsigned char * flagarray;
unsigned long flagarray_slots; unsigned long flagarray_slots;
// how to handle this virtual mess? // how to handle this virtual mess?
std::vector <void *> block_events; std::vector <t_virtual *> block_events;
// no idea what these are // no idea what these are
long unk1; long unk1;
long unk2; long unk2;
@ -570,36 +560,37 @@ namespace DFHack
template <typename T> template <typename T>
struct df_array struct df_array
{ {
inline const T& operator[] (uint32_t index) inline T& operator[] (uint32_t index)
{ {
return array[index]; return array[index];
}; };
private: T * array;
T array[];
}; };
template <typename T> template <typename T>
struct df_2darray struct df_2darray
{ {
inline const df_array<T>& operator[] (uint32_t index) inline df_array<T>& operator[] (uint32_t index)
{ {
return array[index]; return array[index];
}; };
private:
df_array <T> * array; df_array <T> * array;
}; };
template <typename T> template <typename T>
struct df_3darray struct df_3darray
{ {
inline const df_2darray<T>& operator[] (uint32_t index) inline df_2darray<T>& operator[] (uint32_t index)
{ {
return array[index]; return array[index];
}; };
private: inline bool operator! ()
{
return !array;
}
df_2darray <T> * array; df_2darray <T> * array;
}; };
struct map_data struct map_data
{ {
df_3darray<df_block *> map_data; df_3darray<df_block *> map;
std::vector <void *> unk1; std::vector <void *> unk1;
void * unk2; void * unk2;
uint32_t x_size_blocks; uint32_t x_size_blocks;
@ -620,6 +611,8 @@ namespace DFHack
class DFHACK_EXPORT Maps : public Module class DFHACK_EXPORT Maps : public Module
{ {
public: public:
// the map data of DF, as we know it.
map_data * mdata;
Maps(); Maps();
~Maps(); ~Maps();
@ -724,7 +717,7 @@ namespace DFHack
/** /**
* Get the address of a block or 0 if block is not valid * Get the address of a block or 0 if block is not valid
*/ */
uint32_t getBlockPtr (uint32_t blockx, uint32_t blocky, uint32_t blockz); df_block * getBlockPtr (uint32_t blockx, uint32_t blocky, uint32_t blockz);
/// read the whole map block at block coords (see DFTypes.h for the block structure) /// read the whole map block at block coords (see DFTypes.h for the block structure)
bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer); bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer);
@ -763,11 +756,11 @@ namespace DFHack
/// block event reading - mineral veins, what's under ice, blood smears and mud /// block event reading - mineral veins, what's under ice, blood smears and mud
bool ReadVeins(uint32_t x, uint32_t y, uint32_t z, bool ReadVeins(uint32_t x, uint32_t y, uint32_t z,
std::vector<t_vein>* veins, std::vector<t_vein *>* veins,
std::vector<t_frozenliquidvein>* ices = 0, std::vector<t_frozenliquidvein *>* ices = 0,
std::vector<t_spattervein>* splatter = 0, std::vector<t_spattervein *>* splatter = 0,
std::vector<t_grassvein>* grass = 0, std::vector<t_grassvein *>* grass = 0,
std::vector<t_worldconstruction>* constructions = 0 std::vector<t_worldconstruction *>* constructions = 0
); );
/// read all plants in this block /// read all plants in this block
bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants); bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants);

@ -373,7 +373,7 @@ ItemDesc::ItemDesc(uint32_t VTable, Process *p)
this->vtable = VTable; this->vtable = VTable;
this->p = p; this->p = p;
this->className = p->readClassName(VTable).substr(5); this->className = p->readClassName((void *) VTable).substr(5);
this->className.resize(this->className.size()-2); this->className.resize(this->className.size()-2);
this->hasDecoration = false; this->hasDecoration = false;
@ -573,7 +573,7 @@ bool Items::readItemRefs(const dfh_item &item, const ClassNameCheck &classname,
for (uint32_t i=0; i<p_refs.size(); i++) for (uint32_t i=0; i<p_refs.size(); i++)
{ {
uint32_t vtbl = d->owner->readDWord(p_refs[i]); uint32_t vtbl = d->owner->readDWord(p_refs[i]);
if (classname(d->owner, vtbl)) if (classname(d->owner, (void *) vtbl))
values.push_back(int32_t(d->owner->readDWord(p_refs[i] + 4))); values.push_back(int32_t(d->owner->readDWord(p_refs[i] + 4)));
} }
@ -587,7 +587,7 @@ bool Items::removeItemOwner(dfh_item &item, Creatures *creatures)
for (uint32_t i=0; i<p_refs.size(); i++) for (uint32_t i=0; i<p_refs.size(); i++)
{ {
uint32_t vtbl = d->owner->readDWord(p_refs[i]); uint32_t vtbl = d->owner->readDWord(p_refs[i]);
if (!d->isOwnerRefClass(d->owner, vtbl)) continue; if (!d->isOwnerRefClass(d->owner, (void *) vtbl)) continue;
int32_t oid = d->owner->readDWord(p_refs[i]+4); int32_t oid = d->owner->readDWord(p_refs[i]+4);
int32_t ix = creatures->FindIndexById(oid); int32_t ix = creatures->FindIndexById(oid);

@ -68,45 +68,20 @@ const char * DFHack::sa_feature(e_feature index)
struct Maps::Private struct Maps::Private
{ {
uint32_t * block;
uint32_t x_block_count, y_block_count, z_block_count;
int32_t regionX, regionY, regionZ;
uint32_t worldSizeX, worldSizeY; uint32_t worldSizeX, worldSizeY;
uint32_t maps_module; uint32_t maps_module;
struct t_offsets struct t_offsets
{ {
uint32_t map_offset;// = d->offset_descriptor->getAddress ("map_data"); // FIXME: those need a rework really. Why did Toady use virtual inheritance for such vastly different types anyway?
uint32_t x_count_offset;// = d->offset_descriptor->getAddress ("x_count"); void * vein_mineral_vptr;
uint32_t y_count_offset;// = d->offset_descriptor->getAddress ("y_count"); void * vein_ice_vptr;
uint32_t z_count_offset;// = d->offset_descriptor->getAddress ("z_count"); void * vein_spatter_vptr;
/* void * vein_grass_vptr;
Block void * vein_worldconstruction_vptr;
*/
uint32_t tile_type_offset;// = d->offset_descriptor->getOffset ("type");
uint32_t designation_offset;// = d->offset_descriptor->getOffset ("designation");
uint32_t occupancy_offset;// = d->offset_descriptor->getOffset ("occupancy");
uint32_t biome_stuffs;// = d->offset_descriptor->getOffset ("biome_stuffs");
uint32_t veinvector;// = d->offset_descriptor->getOffset ("v_vein");
uint32_t vegvector;
uint32_t temperature1_offset;
uint32_t temperature2_offset;
uint32_t global_feature_offset;
uint32_t local_feature_offset;
uint32_t mystery;
uint32_t vein_mineral_vptr;
uint32_t vein_ice_vptr;
uint32_t vein_spatter_vptr;
uint32_t vein_grass_vptr;
uint32_t vein_worldconstruction_vptr;
/* /*
GEOLOGY GEOLOGY
*/ */
uint32_t region_x_offset;// = minfo->getAddress ("region_x");
uint32_t region_y_offset;// = minfo->getAddress ("region_y");
uint32_t region_z_offset;// = minfo->getAddress ("region_z");
uint32_t world_regions;// mem->getAddress ("ptr2_region_array"); uint32_t world_regions;// mem->getAddress ("ptr2_region_array");
uint32_t region_size;// = minfo->getHexValue ("region_size"); uint32_t region_size;// = minfo->getHexValue ("region_size");
uint32_t region_geo_index_offset;// = minfo->getOffset ("region_geo_index_off"); uint32_t region_geo_index_offset;// = minfo->getOffset ("region_geo_index_off");
@ -119,18 +94,19 @@ struct Maps::Private
/* /*
FEATURES FEATURES
*/ */
// FIXME: replace with a struct pointer, eventually. needs to be mapped out first
uint32_t world_data; uint32_t world_data;
uint32_t local_f_start; // offset from world_data or absolute address. uint32_t local_f_start; // offset from world_data
// FIXME: replace by virtual function call
uint32_t local_material; uint32_t local_material;
// FIXME: replace by virtual function call
uint32_t local_submaterial; uint32_t local_submaterial;
uint32_t global_vector; // offset from world_data or absolute address. uint32_t global_vector; // offset from world_data
uint32_t global_funcptr; uint32_t global_funcptr;
// FIXME: replace by virtual function call
uint32_t global_material; uint32_t global_material;
// FIXME: replace by virtual function call
uint32_t global_submaterial; uint32_t global_submaterial;
/*
* Vegetation
*/
uint32_t tree_desc_offset;
} offsets; } offsets;
Process * owner; Process * owner;
@ -158,7 +134,6 @@ Maps::Maps()
d = new Private; d = new Private;
Process *p = d->owner = c.p; Process *p = d->owner = c.p;
d->Inited = d->FeaturesStarted = d->Started = false; d->Inited = d->FeaturesStarted = d->Started = false;
d->block = NULL;
DFHack::VersionInfo * mem = c.vinfo; DFHack::VersionInfo * mem = c.vinfo;
Private::t_offsets &off = d->offsets; Private::t_offsets &off = d->offsets;
@ -167,37 +142,10 @@ Maps::Maps()
// get the offsets once here // get the offsets once here
OffsetGroup *OG_Maps = mem->getGroup("Maps"); OffsetGroup *OG_Maps = mem->getGroup("Maps");
off.world_data = OG_Maps->getAddress("world_data"); off.world_data = OG_Maps->getAddress("world_data");
{ {
off.map_offset = OG_Maps->getAddress ("map_data"); mdata = (map_data *) OG_Maps->getAddress ("map_data");
off.x_count_offset = OG_Maps->getAddress ("x_count_block");
off.y_count_offset = OG_Maps->getAddress ("y_count_block");
off.z_count_offset = OG_Maps->getAddress ("z_count_block");
off.region_x_offset = OG_Maps->getAddress ("region_x");
off.region_y_offset = OG_Maps->getAddress ("region_y");
off.region_z_offset = OG_Maps->getAddress ("region_z");
off.world_size_x = OG_Maps->getOffset ("world_size_x_from_wdata"); off.world_size_x = OG_Maps->getOffset ("world_size_x_from_wdata");
off.world_size_y = OG_Maps->getOffset ("world_size_y_from_wdata"); off.world_size_y = OG_Maps->getOffset ("world_size_y_from_wdata");
OffsetGroup *OG_MapBlock = OG_Maps->getGroup("block");
{
off.tile_type_offset = OG_MapBlock->getOffset ("type");
off.designation_offset = OG_MapBlock->getOffset ("designation");
off.occupancy_offset = OG_MapBlock->getOffset("occupancy");
off.biome_stuffs = OG_MapBlock->getOffset ("biome_stuffs");
off.veinvector = OG_MapBlock->getOffset ("vein_vector");
off.local_feature_offset = OG_MapBlock->getOffset ("feature_local");
off.global_feature_offset = OG_MapBlock->getOffset ("feature_global");
off.temperature1_offset = OG_MapBlock->getOffset ("temperature1");
off.temperature2_offset = OG_MapBlock->getOffset ("temperature2");
}
try
{
off.mystery = OG_MapBlock->getOffset ("mystery_offset");
}
catch(Error::AllMemdef &)
{
off.mystery = 0;
}
try try
{ {
OffsetGroup *OG_Geology = OG_Maps->getGroup("geology"); OffsetGroup *OG_Geology = OG_Maps->getGroup("geology");
@ -229,17 +177,6 @@ Maps::Maps()
{ {
d->hasFeatures = false; d->hasFeatures = false;
} }
try
{
OffsetGroup * OG_Veg = c.vinfo->getGroup("Vegetation");
off.vegvector = OG_MapBlock->getOffset ("vegetation_vector");
off.tree_desc_offset = OG_Veg->getOffset ("tree_desc_offset");
}
catch(Error::AllMemdef &)
{
d->hasVeggies = false;
}
} }
d->OG_vector = mem->getGroup("vector"); d->OG_vector = mem->getGroup("vector");
@ -280,52 +217,27 @@ bool Maps::Start()
Process *p = d->owner; Process *p = d->owner;
Private::t_offsets &off = d->offsets; Private::t_offsets &off = d->offsets;
// get the map pointer // is there a map?
uint32_t x_array_loc = p->readDWord (off.map_offset); //uint32_t x_array_loc = p->readDWord (off.map_offset);
if (!x_array_loc) if (!mdata->map)
{ {
return false; return false;
} }
// get the size // get the size
uint32_t mx, my, mz; uint32_t & mx = mdata->x_size_blocks;
mx = d->x_block_count = p->readDWord (off.x_count_offset); uint32_t & my = mdata->y_size_blocks;
my = d->y_block_count = p->readDWord (off.y_count_offset); uint32_t & mz = mdata->z_size_blocks;
mz = d->z_block_count = p->readDWord (off.z_count_offset);
// test for wrong map dimensions // test for wrong map dimensions
if (mx == 0 || mx > 48 || my == 0 || my > 48 || mz == 0) if (mx == 0 || mx > 48 || my == 0 || my > 48 || mz == 0)
{ {
cout << hex << off.x_count_offset << " " << off.y_count_offset << " " << off.z_count_offset << endl; cerr << hex << &mx << " " << &my << " " << &mz << endl;
cout << dec << mx << " "<< my << " "<< mz << endl; cout << dec << mx << " "<< my << " "<< mz << endl;
// FIXME: this should be avoided!
throw Error::BadMapDimensions(mx, my); throw Error::BadMapDimensions(mx, my);
//return false;
} }
// read position of the region inside DF world
p->readDWord (off.region_x_offset, (uint32_t &) d->regionX);
p->readDWord (off.region_y_offset, (uint32_t &) d->regionY);
p->readDWord (off.region_z_offset, (uint32_t &) d->regionZ);
// alloc array for pointers to all blocks
d->block = new uint32_t[mx*my*mz];
uint32_t *temp_x = new uint32_t[mx];
uint32_t *temp_y = new uint32_t[my];
p->read (x_array_loc, mx * sizeof (uint32_t), (uint8_t *) temp_x);
for (uint32_t x = 0; x < mx; x++)
{
p->read (temp_x[x], my * sizeof (uint32_t), (uint8_t *) temp_y);
// y -> map column
for (uint32_t y = 0; y < my; y++)
{
p->read (temp_y[y],
mz * sizeof (uint32_t),
(uint8_t *) (d->block + x*my*mz + y*mz));
}
}
delete [] temp_x;
delete [] temp_y;
d->Started = true; d->Started = true;
return true; return true;
} }
@ -334,27 +246,22 @@ bool Maps::Start()
void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z) void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z)
{ {
MAPS_GUARD MAPS_GUARD
x = d->x_block_count; x = mdata->x_size_blocks;
y = d->y_block_count; y = mdata->y_size_blocks;
z = d->z_block_count; z = mdata->z_size_blocks;
} }
// getter for map position // getter for map position
void Maps::getPosition (int32_t& x, int32_t& y, int32_t& z) void Maps::getPosition (int32_t& x, int32_t& y, int32_t& z)
{ {
MAPS_GUARD MAPS_GUARD
x = d->regionX; x = mdata->x_area_offset;
y = d->regionY; y = mdata->y_area_offset;
z = d->regionZ; z = mdata->z_area_offset;
} }
bool Maps::Finish() bool Maps::Finish()
{ {
if (d->block != NULL)
{
delete [] d->block;
d->block = NULL;
}
return true; return true;
} }
@ -365,37 +272,68 @@ bool Maps::Finish()
bool Maps::isValidBlock (uint32_t x, uint32_t y, uint32_t z) bool Maps::isValidBlock (uint32_t x, uint32_t y, uint32_t z)
{ {
MAPS_GUARD MAPS_GUARD
if ( x >= d->x_block_count || y >= d->y_block_count || z >= d->z_block_count) if(x >= mdata->x_size_blocks || y >= mdata->y_size_blocks || z >= mdata->z_size_blocks)
return false; return false;
return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z] != 0; return mdata->map[x][y][z] != 0;
} }
uint32_t Maps::getBlockPtr (uint32_t x, uint32_t y, uint32_t z) df_block* Maps::getBlockPtr (uint32_t x, uint32_t y, uint32_t z)
{ {
MAPS_GUARD MAPS_GUARD
if ( x >= d->x_block_count || y >= d->y_block_count || z >= d->z_block_count) if(x >= mdata->x_size_blocks || y >= mdata->y_size_blocks || z >= mdata->z_size_blocks)
return 0; return 0;
return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; /*
cerr << hex;
cerr << "Map data address = " << mdata << endl;
cerr << "3D = " << &mdata->map << endl;
cerr << "3D array start = " << mdata->map.array << endl;
*/
df_2darray<DFHack::df_block*> & arr2d = mdata->map[x];//[y][z];
df_array<DFHack::df_block*> & arr = arr2d[y];
/*df_block * b= arr[z];
cerr << "2D address = " << &arr2d << endl;
cerr << "2D array start = " << arr2d.array << endl;
cerr << "1D address = " << &arr << endl;
cerr << "1D array start = " << arr.array << endl;
cerr << "block address = " << b << endl;
cerr << "-----------------------------" << endl;
cerr << dec << flush;*/
return mdata->map[x][y][z];
} }
bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer) bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer)
{ {
MAPS_GUARD MAPS_GUARD
Process *p = d->owner; Process *p = d->owner;
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
buffer->position = DFCoord(x,y,z); buffer->position = DFCoord(x,y,z);
p->read (addr + d->offsets.tile_type_offset, sizeof (buffer->tiletypes), (uint8_t *) buffer->tiletypes);
p->read (addr + d->offsets.designation_offset, sizeof (buffer->designation), (uint8_t *) buffer->designation); //p->read (addr + d->offsets.tile_type_offset, sizeof (buffer->tiletypes), (uint8_t *) buffer->tiletypes);
p->read (addr + d->offsets.occupancy_offset, sizeof (buffer->occupancy), (uint8_t *) buffer->occupancy); memcpy(buffer->tiletypes,block->tiletype, sizeof(tiletypes40d));
p->read (addr + d->offsets.biome_stuffs, sizeof (biome_indices40d), (uint8_t *) buffer->biome_indices);
//p->read (addr + d->offsets.designation_offset, sizeof (buffer->designation), (uint8_t *) buffer->designation);
memcpy(buffer->designation,block->designation, sizeof(designations40d));
//p->read (addr + d->offsets.occupancy_offset, sizeof (buffer->occupancy), (uint8_t *) buffer->occupancy);
memcpy(buffer->occupancy,block->occupancy, sizeof(occupancies40d));
//p->read (addr + d->offsets.biome_stuffs, sizeof (biome_indices40d), (uint8_t *) buffer->biome_indices);
memcpy(buffer->biome_indices,block->region_offset, sizeof(block->region_offset));
buffer->global_feature = block->global_feature;
buffer->local_feature = block->local_feature;
buffer->mystery = block->mystery;
/*
p->readWord(addr + d->offsets.global_feature_offset, (uint16_t&) buffer->global_feature); p->readWord(addr + d->offsets.global_feature_offset, (uint16_t&) buffer->global_feature);
p->readWord(addr + d->offsets.local_feature_offset, (uint16_t&)buffer->local_feature); p->readWord(addr + d->offsets.local_feature_offset, (uint16_t&)buffer->local_feature);
p->readDWord(addr + d->offsets.mystery, (uint32_t&)buffer->mystery); p->readDWord(addr + d->offsets.mystery, (uint32_t&)buffer->mystery);
buffer->origin = addr; */
uint32_t addr_of_struct = p->readDWord(addr); // FIXME: not 64-bit safe
buffer->blockflags.whole = p->readDWord(addr_of_struct); buffer->origin = (uint32_t) &block;
//uint32_t addr_of_struct = p->readDWord(addr);
buffer->blockflags.whole = *(uint32_t*) block->flagarray;
return true; return true;
} }
return false; return false;
@ -408,10 +346,10 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer
bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer) bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
d->owner->read (addr + d->offsets.tile_type_offset, sizeof (tiletypes40d), (uint8_t *) buffer); memcpy(buffer, block->tiletype, sizeof(tiletypes40d));
return true; return true;
} }
return false; return false;
@ -420,10 +358,11 @@ bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buff
bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer) bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
d->owner->write (addr + d->offsets.tile_type_offset, sizeof (tiletypes40d), (uint8_t *) buffer); memcpy(block->tiletype, buffer, sizeof(tiletypes40d));
//d->owner->write (addr + d->offsets.tile_type_offset, sizeof (tiletypes40d), (uint8_t *) buffer);
return true; return true;
} }
return false; return false;
@ -432,33 +371,31 @@ bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buf
/* /*
* Dirty bit * Dirty bit
*/ */
//FIXME: this is bullshit
bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit) bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if(addr) if (block)
{ {
Process * p = d->owner; if(!block->flagarray)
uint32_t addr_of_struct = p->readDWord(addr); return false;
dirtybit = p->readDWord(addr_of_struct) & 1; dirtybit = ((t_blockflags *)block->flagarray)->bits.designated;
return true; return true;
} }
return false; return false;
} }
//FIXME: this is bullshit
bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit) bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
Process * p = d->owner; if(!block->flagarray)
uint32_t addr_of_struct = p->readDWord(addr); return false;
uint32_t dirtydword = p->readDWord(addr_of_struct); t_blockflags & flagz = (*(t_blockflags *)block->flagarray);
dirtydword &= 0xFFFFFFFE; flagz.bits.designated = dirtybit;
dirtydword |= (uint32_t) dirtybit;
p->writeDWord (addr_of_struct, dirtydword);
return true; return true;
} }
return false; return false;
@ -467,28 +404,31 @@ bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
/* /*
* Block flags * Block flags
*/ */
//FIXME: this is bullshit
bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags) bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if(addr) if (block)
{ {
Process * p = d->owner; if(!block->flagarray)
uint32_t addr_of_struct = p->readDWord(addr); return false;
blockflags.whole = p->readDWord(addr_of_struct); blockflags = *(t_blockflags *) block->flagarray;
return true; return true;
} }
return false; return false;
} }
//FIXME: this is bullshit
bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags) bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
Process * p = d->owner; if(!block->flagarray)
uint32_t addr_of_struct = p->readDWord(addr); return false;
p->writeDWord (addr_of_struct, blockflags.whole); t_blockflags & bf = *(t_blockflags *) block->flagarray;
bf.whole = blockflags.whole;
return true; return true;
} }
return false; return false;
@ -500,10 +440,10 @@ bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags bloc
bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer) bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
d->owner->read (addr + d->offsets.designation_offset, sizeof (designations40d), (uint8_t *) buffer); memcpy(buffer, block->designation, sizeof(designations40d));
return true; return true;
} }
return false; return false;
@ -512,10 +452,10 @@ bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d
bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer) bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
d->owner->write (addr + d->offsets.designation_offset, sizeof (designations40d), (uint8_t *) buffer); memcpy(block->designation, buffer, sizeof(designations40d));
return true; return true;
} }
return false; return false;
@ -527,10 +467,10 @@ bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40
bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer) bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
d->owner->read (addr + d->offsets.occupancy_offset, sizeof (occupancies40d), (uint8_t *) buffer); memcpy(buffer, block->occupancy, sizeof(occupancies40d));
return true; return true;
} }
return false; return false;
@ -539,10 +479,10 @@ bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *bu
bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer) bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
d->owner->write (addr + d->offsets.occupancy_offset, sizeof (occupancies40d), (uint8_t *) buffer); memcpy(block->occupancy, buffer, sizeof(occupancies40d));
return true; return true;
} }
return false; return false;
@ -554,13 +494,13 @@ bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *b
bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2) bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
if(temp1) if(temp1)
d->owner->read (addr + d->offsets.temperature1_offset, sizeof (t_temperatures), (uint8_t *) temp1); memcpy(temp1, block->temperature_1, sizeof(t_temperatures));
if(temp2) if(temp2)
d->owner->read (addr + d->offsets.temperature2_offset, sizeof (t_temperatures), (uint8_t *) temp2); memcpy(temp2, block->temperature_2, sizeof(t_temperatures));
return true; return true;
} }
return false; return false;
@ -568,13 +508,13 @@ bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *
bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2) bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
if(temp1) if(temp1)
d->owner->write (addr + d->offsets.temperature1_offset, sizeof (t_temperatures), (uint8_t *) temp1); memcpy(block->temperature_1, temp1, sizeof(t_temperatures));
if(temp2) if(temp2)
d->owner->write (addr + d->offsets.temperature2_offset, sizeof (t_temperatures), (uint8_t *) temp2); memcpy(block->temperature_2, temp2, sizeof(t_temperatures));
return true; return true;
} }
return false; return false;
@ -586,10 +526,10 @@ bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures
bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices40d *buffer) bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
d->owner->read (addr + d->offsets.biome_stuffs, sizeof (biome_indices40d), (uint8_t *) buffer); memcpy(buffer, block->region_offset,sizeof(biome_indices40d));
return true; return true;
} }
return false; return false;
@ -606,10 +546,6 @@ bool Maps::StopFeatures()
} }
return false; return false;
} }
typedef uint32_t _DWORD;
typedef uint8_t _BYTE;
#define BYTEn(x, n) (*((_BYTE*)&(x)+n))
#define BYTE4(x) BYTEn(x, 4)
bool Maps::StartFeatures() bool Maps::StartFeatures()
{ {
@ -617,7 +553,7 @@ bool Maps::StartFeatures()
if(d->FeaturesStarted) return true; if(d->FeaturesStarted) return true;
if(!d->hasFeatures) return false; if(!d->hasFeatures) return false;
// can't be used without a map! // can't be used without a map!
if(!d->block) if(!mdata->map)
return false; return false;
Process * p = d->owner; Process * p = d->owner;
@ -645,16 +581,16 @@ bool Maps::StartFeatures()
const uint32_t loc_sub_mat_offset = off.local_submaterial; const uint32_t loc_sub_mat_offset = off.local_submaterial;
const uint32_t sizeof_16vec = 16* sizeof_vec; const uint32_t sizeof_16vec = 16* sizeof_vec;
for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++) for(uint32_t blockX = 0; blockX < mdata->x_size_blocks; blockX ++)
for(uint32_t blockY = 0; blockY < d->y_block_count; blockY ++) for(uint32_t blockY = 0; blockY < mdata->y_size_blocks; blockY ++)
{ {
// regionX and regionY are in embark squares! // regionX and regionY are in embark squares!
// we convert to full region tiles // we convert to full region tiles
// this also works in adventure mode // this also works in adventure mode
// region X coord - whole regions // region X coord - whole regions
uint32_t region_x = ( (blockX / 3) + d->regionX ) / 16; uint32_t region_x = ( (blockX / 3) + mdata->x_area_offset ) / 16;
// region Y coord - whole regions // region Y coord - whole regions
uint32_t region_y = ( (blockY / 3) + d->regionY ) / 16; uint32_t region_y = ( (blockY / 3) + mdata->y_area_offset ) / 16;
uint32_t bigregion_x = region_x / 16; uint32_t bigregion_x = region_x / 16;
uint32_t bigregion_y = region_y / 16; uint32_t bigregion_y = region_y / 16;
uint32_t sub_x = region_x % 16; uint32_t sub_x = region_x % 16;
@ -694,7 +630,7 @@ bool Maps::StartFeatures()
t_feature tftemp; t_feature tftemp;
tftemp.discovered = false; //= p->readDWord(cur_ptr + 4); tftemp.discovered = false; //= p->readDWord(cur_ptr + 4);
tftemp.origin = cur_ptr; tftemp.origin = cur_ptr;
string name = p->readClassName(p->readDWord( cur_ptr )); string name = p->readClassName((void *)p->readDWord( cur_ptr ));
if(name == "feature_init_deep_special_tubest") if(name == "feature_init_deep_special_tubest")
{ {
tftemp.main_material = p->readWord( cur_ptr + loc_main_mat_offset ); tftemp.main_material = p->readWord( cur_ptr + loc_main_mat_offset );
@ -739,7 +675,7 @@ bool Maps::StartFeatures()
temp.discovered = false; temp.discovered = false;
// FIXME: use the memory_info cache mechanisms // FIXME: use the memory_info cache mechanisms
string name = p->readClassName(p->readDWord( feat_ptr)); string name = p->readClassName((void *)p->readDWord( feat_ptr));
if(name == "feature_init_underworld_from_layerst") if(name == "feature_init_underworld_from_layerst")
{ {
temp.main_material = p->readWord( feat_ptr + glob_main_mat_offset ); temp.main_material = p->readWord( feat_ptr + glob_main_mat_offset );
@ -781,12 +717,11 @@ std::vector <t_feature *> * Maps::GetLocalFeatures(DFCoord coord)
bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global) bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
Process * p = d->owner; local = block->local_feature;
p->readWord(addr + d->offsets.global_feature_offset, (uint16_t&) global); global = block->global_feature;
p->readWord(addr + d->offsets.local_feature_offset, (uint16_t&)local);
return true; return true;
} }
return false; return false;
@ -795,12 +730,11 @@ bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int
bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int16_t & local, const int16_t & global) bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int16_t & local, const int16_t & global)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
Process * p = d->owner; block->local_feature = local;
p->writeWord(addr + d->offsets.global_feature_offset, (const uint16_t&) global); block->global_feature = global;
p->writeWord(addr + d->offsets.local_feature_offset, (const uint16_t&) local);
return true; return true;
} }
return false; return false;
@ -857,11 +791,10 @@ bool Maps::ReadFeatures(mapblock40d * block, t_feature ** local, t_feature ** gl
bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local) bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
Process * p = d->owner; block->local_feature = local;
p->writeWord(addr + d->offsets.local_feature_offset, (uint16_t&)local);
return true; return true;
} }
return false; return false;
@ -870,11 +803,10 @@ bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t loca
bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global) bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global)
{ {
MAPS_GUARD MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if (addr) if (block)
{ {
Process * p = d->owner; block->global_feature = global;
p->writeWord(addr + d->offsets.global_feature_offset, (uint16_t&)global);
return true; return true;
} }
return false; return false;
@ -883,17 +815,12 @@ bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t glo
/* /*
* Block events * Block events
*/ */
bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein>* veins, vector <t_frozenliquidvein>* ices, vector <t_spattervein> *splatter, vector <t_grassvein> *grass, vector <t_worldconstruction> *constructions) bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein *>* veins, vector <t_frozenliquidvein *>* ices, vector <t_spattervein *> *splatter, vector <t_grassvein *> *grass, vector <t_worldconstruction *> *constructions)
{ {
MAPS_GUARD MAPS_GUARD
t_vein v;
t_frozenliquidvein fv;
t_spattervein sv;
t_grassvein gv;
t_worldconstruction wcv;
Process* p = d->owner; Process* p = d->owner;
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if(veins) veins->clear(); if(veins) veins->clear();
if(ices) ices->clear(); if(ices) ices->clear();
if(splatter) splatter->clear(); if(splatter) splatter->clear();
@ -901,62 +828,41 @@ bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein>* veins,
if(constructions) constructions->clear(); if(constructions) constructions->clear();
Private::t_offsets &off = d->offsets; Private::t_offsets &off = d->offsets;
if (!addr) return false; if (!block)
// veins are stored as a vector of pointers to veins return false;
/*pointer is 4 bytes! we work with a 32bit program here, no matter what architecture we compile khazad for*/ uint32_t size = block->block_events.size();
DfVector <uint32_t> p_veins (addr + off.veinvector);
uint32_t size = p_veins.size();
// read all veins // read all veins
for (uint32_t i = 0; i < size;i++) for (uint32_t i = 0; i < size;i++)
{ {
retry: retry:
// read the vein pointer from the vector // read the vein pointer from the vector
uint32_t temp = p_veins[i]; t_virtual * temp = block->block_events[i];
uint32_t type = p->readDWord(temp); void * type = temp->vptr;
if(type == off.vein_mineral_vptr) if(type == (void *) off.vein_mineral_vptr)
{ {
if(!veins) continue; if(!veins) continue;
// read the vein data (dereference pointer)
p->read (temp, sizeof(t_vein), (uint8_t *) &v);
v.address_of = temp;
// store it in the vector // store it in the vector
veins->push_back (v); veins->push_back ((t_vein *) temp);
} }
else if(type == off.vein_ice_vptr) else if(type == (void *) off.vein_ice_vptr)
{ {
if(!ices) continue; if(!ices) continue;
// read the ice vein data (dereference pointer) ices->push_back ((t_frozenliquidvein *) temp);
p->read (temp, sizeof(t_frozenliquidvein), (uint8_t *) &fv);
fv.address_of = temp;
// store it in the vector
ices->push_back (fv);
} }
else if(type == off.vein_spatter_vptr) else if(type == (void *) off.vein_spatter_vptr)
{ {
if(!splatter) continue; if(!splatter) continue;
// read the splatter vein data (dereference pointer) splatter->push_back ( (t_spattervein *)temp);
p->read (temp, sizeof(t_spattervein), (uint8_t *) &sv);
sv.address_of = temp;
// store it in the vector
splatter->push_back (sv);
} }
else if(type == off.vein_grass_vptr) else if(type == (void *) off.vein_grass_vptr)
{ {
if(!grass) continue; if(!grass) continue;
// read the splatter vein data (dereference pointer) grass->push_back ((t_grassvein *) temp);
p->read (temp, sizeof(t_grassvein), (uint8_t *) &gv);
gv.address_of = temp;
// store it in the vector
grass->push_back (gv);
} }
else if(type == off.vein_worldconstruction_vptr) else if(type == (void *) off.vein_worldconstruction_vptr)
{ {
if(!constructions) continue; if(!constructions) continue;
// read the splatter vein data (dereference pointer) constructions->push_back ((t_worldconstruction *) temp);
p->read (temp, sizeof(t_worldconstruction), (uint8_t *) &wcv);
wcv.address_of = temp;
// store it in the vector
constructions->push_back (wcv);
} }
// previously unseen type of vein // previously unseen type of vein
else else
@ -1086,10 +992,10 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
// regionX is in embark squares // regionX is in embark squares
// regionX/16 is in 16x16 embark square regions // regionX/16 is in 16x16 embark square regions
// i provides -1 .. +1 offset from the current region // i provides -1 .. +1 offset from the current region
int bioRX = d->regionX / 16 + ((i % 3) - 1); int bioRX = mdata->x_area_offset / 16 + ((i % 3) - 1);
if (bioRX < 0) bioRX = 0; if (bioRX < 0) bioRX = 0;
if (bioRX >= worldSizeX) bioRX = worldSizeX - 1; if (bioRX >= worldSizeX) bioRX = worldSizeX - 1;
int bioRY = d->regionY / 16 + ((i / 3) - 1); int bioRY = mdata->y_area_offset / 16 + ((i / 3) - 1);
if (bioRY < 0) bioRY = 0; if (bioRY < 0) bioRY = 0;
if (bioRY >= worldSizeY) bioRY = worldSizeY - 1; if (bioRY >= worldSizeY) bioRY = worldSizeY - 1;
@ -1162,10 +1068,10 @@ bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_pla
{ {
if(!d->hasVeggies || !d->Started) if(!d->hasVeggies || !d->Started)
return false; return false;
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; df_block * block = getBlockPtr(x,y,z);
if(!addr) if(!block)
return false; return false;
Private::t_offsets &off = d->offsets; Private::t_offsets &off = d->offsets;
plants = (std::vector<df_plant *>*) (addr + off.vegvector); plants = &block->plants;
return true; return true;
} }