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);
string raw = readCString(typestring);
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)
{
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?
{
// 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);
}
// 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
bool VersionInfo::resolveClassnameToVPtr(const string classname, uint32_t & vptr)
bool VersionInfo::resolveClassnameToVPtr(const string classname, void * & vptr)
{
// FIXME: another stupid search.
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(d->classes[i]->classname == classname) // got class
{
vptr = d->classes[i]->vtable;
vptr = (void *) d->classes[i]->vtable;
return true;
}
}

@ -228,11 +228,11 @@ namespace DFHack
}
/// 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())
return it->second;
return classNameCache[vptr] = doReadClassName(vptr);
@ -274,13 +274,13 @@ namespace DFHack
bool identified;
uint32_t my_pid;
uint32_t base;
std::map<uint32_t, std::string> classNameCache;
std::map<void *, std::string> classNameCache;
};
class DFHACK_EXPORT ClassNameCheck
{
std::string name;
mutable uint32_t vptr;
mutable void * vptr;
public:
ClassNameCheck() : vptr(0) {};
ClassNameCheck(std::string _name) : name(_name), vptr(0) {};
@ -288,7 +288,7 @@ namespace DFHack
{
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)
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
* 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)

@ -35,7 +35,7 @@ namespace MapExtras
void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & 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);
//iterate through block rows
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--)
{
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;
}
}

@ -145,34 +145,32 @@ namespace DFHack
uint32_t origin;
};
struct t_virtual
{
void * vptr;
};
/**
* mineral vein object - bitmap with a material type
* \ingroup grp_maps
*/
struct t_vein
struct t_vein : public t_virtual
{
uint32_t vtable;
/// index into the inorganic material vector
int32_t type;
/// bit mask describing how the vein maps to the map block
/// assignment[y] & (1 << x) describes the tile (x, y) of the block
int16_t assignment[16];
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
* \ingroup grp_maps
*/
struct t_frozenliquidvein
struct t_frozenliquidvein : public t_virtual
{
uint32_t vtable;
/// a 16x16 array of the original tile types
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
@ -192,9 +190,8 @@ namespace DFHack
* \ingroup grp_maps
* @see PrintSplatterType
*/
struct t_spattervein
struct t_spattervein : public t_virtual
{
uint32_t vtable;
/// generic material.
uint16_t mat1;
/// possibly alignment artifact
@ -208,37 +205,29 @@ namespace DFHack
uint16_t matter_state;
/// 16x16 array of covering 'intensity'
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
* bitmap of density (max = 100) with plant material type
* \ingroup grp_maps
*/
struct t_grassvein
struct t_grassvein : public t_virtual
{
uint32_t vtable;
/// material vector index
uint32_t material;
/// 16x16 array of covering 'intensity'
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.
* \ingroup grp_maps
*/
struct t_worldconstruction
struct t_worldconstruction : public t_virtual
{
uint32_t vtable;
/// material vector index
uint32_t material;
/// 16x16 array of bits
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
unsigned int unk_2: 28;
// 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
* \ingroup grp_maps
*/
typedef uint8_t biome_indices40d [16];
typedef uint8_t biome_indices40d [9];
/**
* 16x16 array of temperatures
* \ingroup grp_maps
@ -527,7 +517,7 @@ namespace DFHack
unsigned char * flagarray;
unsigned long flagarray_slots;
// how to handle this virtual mess?
std::vector <void *> block_events;
std::vector <t_virtual *> block_events;
// no idea what these are
long unk1;
long unk2;
@ -570,36 +560,37 @@ namespace DFHack
template <typename T>
struct df_array
{
inline const T& operator[] (uint32_t index)
inline T& operator[] (uint32_t index)
{
return array[index];
};
private:
T array[];
T * array;
};
template <typename T>
struct df_2darray
{
inline const df_array<T>& operator[] (uint32_t index)
inline df_array<T>& operator[] (uint32_t index)
{
return array[index];
};
private:
df_array <T> * array;
};
template <typename T>
struct df_3darray
{
inline const df_2darray<T>& operator[] (uint32_t index)
inline df_2darray<T>& operator[] (uint32_t index)
{
return array[index];
};
private:
inline bool operator! ()
{
return !array;
}
df_2darray <T> * array;
};
struct map_data
{
df_3darray<df_block *> map_data;
df_3darray<df_block *> map;
std::vector <void *> unk1;
void * unk2;
uint32_t x_size_blocks;
@ -620,6 +611,8 @@ namespace DFHack
class DFHACK_EXPORT Maps : public Module
{
public:
// the map data of DF, as we know it.
map_data * mdata;
Maps();
~Maps();
@ -724,7 +717,7 @@ namespace DFHack
/**
* 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)
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
bool ReadVeins(uint32_t x, uint32_t y, uint32_t z,
std::vector<t_vein>* veins,
std::vector<t_frozenliquidvein>* ices = 0,
std::vector<t_spattervein>* splatter = 0,
std::vector<t_grassvein>* grass = 0,
std::vector<t_worldconstruction>* constructions = 0
std::vector<t_vein *>* veins,
std::vector<t_frozenliquidvein *>* ices = 0,
std::vector<t_spattervein *>* splatter = 0,
std::vector<t_grassvein *>* grass = 0,
std::vector<t_worldconstruction *>* constructions = 0
);
/// read all plants in this block
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->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->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++)
{
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)));
}
@ -587,7 +587,7 @@ bool Items::removeItemOwner(dfh_item &item, Creatures *creatures)
for (uint32_t i=0; i<p_refs.size(); 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 ix = creatures->FindIndexById(oid);

@ -68,45 +68,20 @@ const char * DFHack::sa_feature(e_feature index)
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 maps_module;
struct t_offsets
{
uint32_t map_offset;// = d->offset_descriptor->getAddress ("map_data");
uint32_t x_count_offset;// = d->offset_descriptor->getAddress ("x_count");
uint32_t y_count_offset;// = d->offset_descriptor->getAddress ("y_count");
uint32_t z_count_offset;// = d->offset_descriptor->getAddress ("z_count");
/*
Block
*/
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;
// FIXME: those need a rework really. Why did Toady use virtual inheritance for such vastly different types anyway?
void * vein_mineral_vptr;
void * vein_ice_vptr;
void * vein_spatter_vptr;
void * vein_grass_vptr;
void * vein_worldconstruction_vptr;
/*
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 region_size;// = minfo->getHexValue ("region_size");
uint32_t region_geo_index_offset;// = minfo->getOffset ("region_geo_index_off");
@ -119,18 +94,19 @@ struct Maps::Private
/*
FEATURES
*/
// FIXME: replace with a struct pointer, eventually. needs to be mapped out first
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;
// FIXME: replace by virtual function call
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;
// FIXME: replace by virtual function call
uint32_t global_material;
// FIXME: replace by virtual function call
uint32_t global_submaterial;
/*
* Vegetation
*/
uint32_t tree_desc_offset;
} offsets;
Process * owner;
@ -158,7 +134,6 @@ Maps::Maps()
d = new Private;
Process *p = d->owner = c.p;
d->Inited = d->FeaturesStarted = d->Started = false;
d->block = NULL;
DFHack::VersionInfo * mem = c.vinfo;
Private::t_offsets &off = d->offsets;
@ -167,37 +142,10 @@ Maps::Maps()
// get the offsets once here
OffsetGroup *OG_Maps = mem->getGroup("Maps");
off.world_data = OG_Maps->getAddress("world_data");
{
off.map_offset = 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");
mdata = (map_data *) OG_Maps->getAddress ("map_data");
off.world_size_x = OG_Maps->getOffset ("world_size_x_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
{
OffsetGroup *OG_Geology = OG_Maps->getGroup("geology");
@ -229,17 +177,6 @@ Maps::Maps()
{
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");
@ -280,52 +217,27 @@ bool Maps::Start()
Process *p = d->owner;
Private::t_offsets &off = d->offsets;
// get the map pointer
uint32_t x_array_loc = p->readDWord (off.map_offset);
if (!x_array_loc)
// is there a map?
//uint32_t x_array_loc = p->readDWord (off.map_offset);
if (!mdata->map)
{
return false;
}
// get the size
uint32_t mx, my, mz;
mx = d->x_block_count = p->readDWord (off.x_count_offset);
my = d->y_block_count = p->readDWord (off.y_count_offset);
mz = d->z_block_count = p->readDWord (off.z_count_offset);
uint32_t & mx = mdata->x_size_blocks;
uint32_t & my = mdata->y_size_blocks;
uint32_t & mz = mdata->z_size_blocks;
// test for wrong map dimensions
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;
// FIXME: this should be avoided!
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;
return true;
}
@ -334,27 +246,22 @@ bool Maps::Start()
void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z)
{
MAPS_GUARD
x = d->x_block_count;
y = d->y_block_count;
z = d->z_block_count;
x = mdata->x_size_blocks;
y = mdata->y_size_blocks;
z = mdata->z_size_blocks;
}
// getter for map position
void Maps::getPosition (int32_t& x, int32_t& y, int32_t& z)
{
MAPS_GUARD
x = d->regionX;
y = d->regionY;
z = d->regionZ;
x = mdata->x_area_offset;
y = mdata->y_area_offset;
z = mdata->z_area_offset;
}
bool Maps::Finish()
{
if (d->block != NULL)
{
delete [] d->block;
d->block = NULL;
}
return true;
}
@ -365,37 +272,68 @@ bool Maps::Finish()
bool Maps::isValidBlock (uint32_t x, uint32_t y, uint32_t z)
{
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 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
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 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)
{
MAPS_GUARD
Process *p = d->owner;
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
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.occupancy_offset, sizeof (buffer->occupancy), (uint8_t *) buffer->occupancy);
p->read (addr + d->offsets.biome_stuffs, sizeof (biome_indices40d), (uint8_t *) buffer->biome_indices);
//p->read (addr + d->offsets.tile_type_offset, sizeof (buffer->tiletypes), (uint8_t *) buffer->tiletypes);
memcpy(buffer->tiletypes,block->tiletype, sizeof(tiletypes40d));
//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.local_feature_offset, (uint16_t&)buffer->local_feature);
p->readDWord(addr + d->offsets.mystery, (uint32_t&)buffer->mystery);
buffer->origin = addr;
uint32_t addr_of_struct = p->readDWord(addr);
buffer->blockflags.whole = p->readDWord(addr_of_struct);
*/
// FIXME: not 64-bit safe
buffer->origin = (uint32_t) &block;
//uint32_t addr_of_struct = p->readDWord(addr);
buffer->blockflags.whole = *(uint32_t*) block->flagarray;
return true;
}
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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
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 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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
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 false;
@ -432,33 +371,31 @@ bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buf
/*
* Dirty bit
*/
//FIXME: this is bullshit
bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
Process * p = d->owner;
uint32_t addr_of_struct = p->readDWord(addr);
dirtybit = p->readDWord(addr_of_struct) & 1;
if(!block->flagarray)
return false;
dirtybit = ((t_blockflags *)block->flagarray)->bits.designated;
return true;
}
return false;
}
//FIXME: this is bullshit
bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
Process * p = d->owner;
uint32_t addr_of_struct = p->readDWord(addr);
uint32_t dirtydword = p->readDWord(addr_of_struct);
dirtydword &= 0xFFFFFFFE;
dirtydword |= (uint32_t) dirtybit;
p->writeDWord (addr_of_struct, dirtydword);
if(!block->flagarray)
return false;
t_blockflags & flagz = (*(t_blockflags *)block->flagarray);
flagz.bits.designated = dirtybit;
return true;
}
return false;
@ -467,28 +404,31 @@ bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
/*
* Block flags
*/
//FIXME: this is bullshit
bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
Process * p = d->owner;
uint32_t addr_of_struct = p->readDWord(addr);
blockflags.whole = p->readDWord(addr_of_struct);
if(!block->flagarray)
return false;
blockflags = *(t_blockflags *) block->flagarray;
return true;
}
return false;
}
//FIXME: this is bullshit
bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
Process * p = d->owner;
uint32_t addr_of_struct = p->readDWord(addr);
p->writeDWord (addr_of_struct, blockflags.whole);
if(!block->flagarray)
return false;
t_blockflags & bf = *(t_blockflags *) block->flagarray;
bf.whole = blockflags.whole;
return true;
}
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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
d->owner->read (addr + d->offsets.designation_offset, sizeof (designations40d), (uint8_t *) buffer);
memcpy(buffer, block->designation, sizeof(designations40d));
return true;
}
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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
d->owner->write (addr + d->offsets.designation_offset, sizeof (designations40d), (uint8_t *) buffer);
memcpy(block->designation, buffer, sizeof(designations40d));
return true;
}
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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
d->owner->read (addr + d->offsets.occupancy_offset, sizeof (occupancies40d), (uint8_t *) buffer);
memcpy(buffer, block->occupancy, sizeof(occupancies40d));
return true;
}
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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
d->owner->write (addr + d->offsets.occupancy_offset, sizeof (occupancies40d), (uint8_t *) buffer);
memcpy(block->occupancy, buffer, sizeof(occupancies40d));
return true;
}
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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
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)
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 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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
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)
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 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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
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 false;
@ -606,10 +546,6 @@ bool Maps::StopFeatures()
}
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()
{
@ -617,7 +553,7 @@ bool Maps::StartFeatures()
if(d->FeaturesStarted) return true;
if(!d->hasFeatures) return false;
// can't be used without a map!
if(!d->block)
if(!mdata->map)
return false;
Process * p = d->owner;
@ -645,16 +581,16 @@ bool Maps::StartFeatures()
const uint32_t loc_sub_mat_offset = off.local_submaterial;
const uint32_t sizeof_16vec = 16* sizeof_vec;
for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++)
for(uint32_t blockY = 0; blockY < d->y_block_count; blockY ++)
for(uint32_t blockX = 0; blockX < mdata->x_size_blocks; blockX ++)
for(uint32_t blockY = 0; blockY < mdata->y_size_blocks; blockY ++)
{
// regionX and regionY are in embark squares!
// we convert to full region tiles
// this also works in adventure mode
// 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
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_y = region_y / 16;
uint32_t sub_x = region_x % 16;
@ -694,7 +630,7 @@ bool Maps::StartFeatures()
t_feature tftemp;
tftemp.discovered = false; //= p->readDWord(cur_ptr + 4);
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")
{
tftemp.main_material = p->readWord( cur_ptr + loc_main_mat_offset );
@ -739,7 +675,7 @@ bool Maps::StartFeatures()
temp.discovered = false;
// 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")
{
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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
Process * p = d->owner;
p->readWord(addr + d->offsets.global_feature_offset, (uint16_t&) global);
p->readWord(addr + d->offsets.local_feature_offset, (uint16_t&)local);
local = block->local_feature;
global = block->global_feature;
return true;
}
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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
Process * p = d->owner;
p->writeWord(addr + d->offsets.global_feature_offset, (const uint16_t&) global);
p->writeWord(addr + d->offsets.local_feature_offset, (const uint16_t&) local);
block->local_feature = local;
block->global_feature = global;
return true;
}
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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
Process * p = d->owner;
p->writeWord(addr + d->offsets.local_feature_offset, (uint16_t&)local);
block->local_feature = local;
return true;
}
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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
df_block * block = getBlockPtr(x,y,z);
if (block)
{
Process * p = d->owner;
p->writeWord(addr + d->offsets.global_feature_offset, (uint16_t&)global);
block->global_feature = global;
return true;
}
return false;
@ -883,17 +815,12 @@ bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t glo
/*
* 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
t_vein v;
t_frozenliquidvein fv;
t_spattervein sv;
t_grassvein gv;
t_worldconstruction wcv;
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(ices) ices->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();
Private::t_offsets &off = d->offsets;
if (!addr) return false;
// veins are stored as a vector of pointers to veins
/*pointer is 4 bytes! we work with a 32bit program here, no matter what architecture we compile khazad for*/
DfVector <uint32_t> p_veins (addr + off.veinvector);
uint32_t size = p_veins.size();
if (!block)
return false;
uint32_t size = block->block_events.size();
// read all veins
for (uint32_t i = 0; i < size;i++)
{
retry:
// read the vein pointer from the vector
uint32_t temp = p_veins[i];
uint32_t type = p->readDWord(temp);
if(type == off.vein_mineral_vptr)
t_virtual * temp = block->block_events[i];
void * type = temp->vptr;
if(type == (void *) off.vein_mineral_vptr)
{
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
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;
// read the ice vein data (dereference pointer)
p->read (temp, sizeof(t_frozenliquidvein), (uint8_t *) &fv);
fv.address_of = temp;
// store it in the vector
ices->push_back (fv);
ices->push_back ((t_frozenliquidvein *) temp);
}
else if(type == off.vein_spatter_vptr)
else if(type == (void *) off.vein_spatter_vptr)
{
if(!splatter) continue;
// read the splatter vein data (dereference pointer)
p->read (temp, sizeof(t_spattervein), (uint8_t *) &sv);
sv.address_of = temp;
// store it in the vector
splatter->push_back (sv);
splatter->push_back ( (t_spattervein *)temp);
}
else if(type == off.vein_grass_vptr)
else if(type == (void *) off.vein_grass_vptr)
{
if(!grass) continue;
// read the splatter vein data (dereference pointer)
p->read (temp, sizeof(t_grassvein), (uint8_t *) &gv);
gv.address_of = temp;
// store it in the vector
grass->push_back (gv);
grass->push_back ((t_grassvein *) temp);
}
else if(type == off.vein_worldconstruction_vptr)
else if(type == (void *) off.vein_worldconstruction_vptr)
{
if(!constructions) continue;
// read the splatter vein data (dereference pointer)
p->read (temp, sizeof(t_worldconstruction), (uint8_t *) &wcv);
wcv.address_of = temp;
// store it in the vector
constructions->push_back (wcv);
constructions->push_back ((t_worldconstruction *) temp);
}
// previously unseen type of vein
else
@ -1086,10 +992,10 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
// regionX is in embark squares
// regionX/16 is in 16x16 embark square regions
// 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 >= 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 >= 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)
return false;
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(!addr)
df_block * block = getBlockPtr(x,y,z);
if(!block)
return false;
Private::t_offsets &off = d->offsets;
plants = (std::vector<df_plant *>*) (addr + off.vegvector);
plants = &block->plants;
return true;
}