diff --git a/library/DFContextManager.cpp b/library/DFContextManager.cpp index 5b947894d..46814d90e 100644 --- a/library/DFContextManager.cpp +++ b/library/DFContextManager.cpp @@ -23,10 +23,10 @@ distribution. */ #include "Internal.h" +#include "DFMemInfoManager.h" #include "dfhack/DFProcess.h" #include "dfhack/DFProcessEnumerator.h" -#include "dfhack/DFMemInfoManager.h" #include "dfhack/DFError.h" #include "dfhack/DFContext.h" diff --git a/library/DFMemInfoManager.cpp b/library/DFMemInfoManager.cpp index 4b7f537e0..a2c0140ce 100644 --- a/library/DFMemInfoManager.cpp +++ b/library/DFMemInfoManager.cpp @@ -23,8 +23,9 @@ distribution. */ #include "Internal.h" +#include "DFMemInfoManager.h" + #include "dfhack/DFMemInfo.h" -#include "dfhack/DFMemInfoManager.h" #include "dfhack/DFError.h" using namespace DFHack; diff --git a/library/DFProcessEnumerator.cpp b/library/DFProcessEnumerator.cpp index 8c537c13b..839b59e44 100644 --- a/library/DFProcessEnumerator.cpp +++ b/library/DFProcessEnumerator.cpp @@ -23,10 +23,12 @@ distribution. */ #include "Internal.h" +#include "DFMemInfoManager.h" + #include "dfhack/DFProcessEnumerator.h" #include "dfhack/DFProcess.h" #include "dfhack/DFMemInfo.h" -#include "dfhack/DFMemInfoManager.h" + using namespace DFHack; @@ -223,7 +225,7 @@ uint64_t FileTime_to_POSIX(FILETIME ft) void ProcessEnumerator::Private::EnumPIDs (vector &PIDs) { FILETIME ftCreate, ftExit, ftKernel, ftUser; - + PIDs.clear(); // make sure the vector is clear // Get the list of process identifiers. @@ -254,7 +256,7 @@ void ProcessEnumerator::Private::EnumPIDs (vector &PIDs) } #endif -bool ProcessEnumerator::Refresh( BadProcesses* invalidated_processes) +bool ProcessEnumerator::Refresh( BadProcesses* invalidated_processes ) { // PIDs to process vector PIDs; @@ -330,11 +332,6 @@ bool ProcessEnumerator::Refresh( BadProcesses* invalidated_processes) return false; } -bool ProcessEnumerator::findProcessess() -{ - return Refresh(); -} - uint32_t ProcessEnumerator::size() { return d->Processes.size(); diff --git a/library/include/dfhack/DFContext.h b/library/include/dfhack/DFContext.h index 658d90ee1..04acc52d8 100644 --- a/library/include/dfhack/DFContext.h +++ b/library/include/dfhack/DFContext.h @@ -44,74 +44,78 @@ namespace DFHack class DFContextShared; class WindowIO; class Process; - + class DFHACK_EXPORT Context { public: Context(Process * p); ~Context(); - + bool isValid(); - + bool Attach(); bool Detach(); bool isAttached(); - + /// stop the tracked process bool Suspend(); + /// @return true if the process is stopped bool isSuspended(); - + /// stop the tracked process, asynchronous bool AsyncSuspend(); - + /// resume the tracked process bool Resume(); - + /// forces resume on Windows. This can be a bad thing with multiple tools running! bool ForceResume(); - + memory_info *getMemoryInfo(); Process* getProcess(); - + void ReadRaw (const uint32_t offset, const uint32_t size, uint8_t *target); void WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source); // FIXME: this is crap. - // get the creatures module + + /// get the creatures module Creatures * getCreatures(); - - // get the maps module + + /// get the maps module Maps * getMaps(); - - // get the gui module + + /// get the gui module Gui * getGui(); - // get the world module + /// get the world module World * getWorld(); - - // get the position module + + /// get the position module Position * getPosition(); - - // get the materials module + + /// get the materials module Materials * getMaterials(); - // get the items module + /// get the items module Items * getItems(); - - // get the translation module + + /// get the translation module Translation * getTranslation(); - - // get the vegetation module + + /// get the vegetation module Vegetation * getVegetation(); - - // get the buildings module + + /// get the buildings module Buildings * getBuildings(); - - // get the constructions module + + /// get the constructions module Constructions * getConstructions(); - - // get the Window management and I/O module + + /// get the Window management and I/O module WindowIO * getWindow(); + + // DEAD CODE, WAITING TO BE UPDATED TO DF2010 /* * Effects like mist, dragonfire or dust */ diff --git a/library/include/dfhack/DFContextManager.h b/library/include/dfhack/DFContextManager.h index c3d6b3edf..210fdb835 100644 --- a/library/include/dfhack/DFContextManager.h +++ b/library/include/dfhack/DFContextManager.h @@ -74,7 +74,7 @@ namespace DFHack /** * Get a context by index * @param index index of the context to be returned - * @return pointer to a Context + * @return pointer to a Context. 0 if the index is out of range. */ Context * operator[](uint32_t index); @@ -106,37 +106,37 @@ namespace DFHack public: BadContexts(); /** - * Destructor. - * All Processes and Contexts tracked by the BadContexts object will be destroyed also. - */ + * Destructor. + * All Processes and Contexts tracked by the BadContexts object will be destroyed also. + */ ~BadContexts(); /** - * Test if a Context is among the invalidated Contexts - * @param c pointer to a Context to be checked - * @return true if the Context is among the invalidated. false otherwise. - */ + * Test if a Context is among the invalidated Contexts + * @param c pointer to a Context to be checked + * @return true if the Context is among the invalidated. false otherwise. + */ bool Contains(Context* c); /** - * Test if a Process is among the invalidated Processes/Contexts - * @param p pointer to a Process to be checked - * @see DFHack::Process - * @return true if the Process is among the invalidated. false otherwise. - */ + * Test if a Process is among the invalidated Processes/Contexts + * @param p pointer to a Process to be checked + * @see DFHack::Process + * @return true if the Process is among the invalidated. false otherwise. + */ bool Contains(Process* p); /** - * Get the number of tracked invalid contexts. - * @return Number of tracked invalid contexts - */ + * Get the number of tracked invalid contexts. + * @return Number of tracked invalid contexts + */ uint32_t size(); /** - * Get an invalid Context by index - * @param index index of the invalid Context to be returned - * @return pointer to an invalid Context - */ + * Get an invalid Context by index + * @param index index of the invalid Context to be returned + * @return pointer to an invalid Context + */ Context * operator[](uint32_t index); }; } // namespace DFHack diff --git a/library/include/dfhack/DFMemInfo.h b/library/include/dfhack/DFMemInfo.h index 765483ecc..50a4aa55c 100644 --- a/library/include/dfhack/DFMemInfo.h +++ b/library/include/dfhack/DFMemInfo.h @@ -85,7 +85,7 @@ namespace DFHack uint32_t type_offset; // offset of type data for multiclass vector subs; }; - + class DFHACK_EXPORT memory_info { private: @@ -114,7 +114,7 @@ namespace DFHack int32_t getOffset (const char *); uint32_t getAddress (const char *); uint32_t getHexValue (const char *); - + std::string getString (const std::string&); std::string getProfession(const uint32_t) const; std::string getJob(const uint32_t) const; @@ -154,34 +154,34 @@ namespace DFHack void RebaseVTable(const int32_t offset); void setParentProcess(Process * _p); - + t_class * setClass (const char * classname, uint32_t vptr = 0, uint32_t typeoffset = 0); void setClassChild (t_class * parent, const char * classname, const char * type); - /* + /** * Get a classID from an address. The address has to point to the start of a virtual object (one with a virtual base class) * uses memory reading directly, needs suspend. input = address of the object * fails if it's unable to read from memory */ bool resolveObjectToClassID (const uint32_t address, int32_t & classID); - - /* + + /** * Get a ClassID when you know the classname. can fail if the class is not in the cache */ bool resolveClassnameToClassID (const std::string classname, int32_t & classID); - - /* + + /** * 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 ); - - /* + + /** * Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID) */ bool resolveClassIDToClassname (const int32_t classID, std::string & classname); - - /* + + /** * Get the internal classID->classname mapping (for speed). DO NOT MANIPULATE THE VECTOR! */ const vector * getClassIDMapping(); diff --git a/library/include/dfhack/DFProcess.h b/library/include/dfhack/DFProcess.h index 2fc2620d0..d2f888492 100644 --- a/library/include/dfhack/DFProcess.h +++ b/library/include/dfhack/DFProcess.h @@ -72,92 +72,115 @@ namespace DFHack if (address >= start && address <= end) return true; return false; } - inline void print() - { - std::cout << std::hex << start << " - " << end << "|" << (read ? "r" : "-") << (write ? "w" : "-") << (execute ? "x" : "-") << "|" << name << std::endl; - } + uint8_t * buffer; }; class DFHACK_EXPORT Process { public: - // this is the single most important destructor ever. ~px + /// this is the single most important destructor ever. ~px virtual ~Process(){}; - // Set up stuff so we can read memory, suspends synchronously + /// Set up stuff so we can read memory, suspends synchronously virtual bool attach() = 0; - // detach from DF, resume its execution if it's suspended + /// detach from DF, resume its execution if it's suspended virtual bool detach() = 0; - - // synchronous suspend - // waits for DF to be actually suspended, - // this might take a while depending on implementation + /** + * synchronous suspend + * waits for DF to be actually suspended, + * this might take a while depending on implementation + */ virtual bool suspend() = 0; - // asynchronous suspend to use together with polling and timers + /// asynchronous suspend to use together with polling and timers virtual bool asyncSuspend() = 0; - // resume DF execution + /// resume DF execution virtual bool resume() = 0; - // force-resume DF execution + /// force-resume DF execution virtual bool forceresume() = 0; - + + /// read a 8-byte integer virtual uint64_t readQuad(const uint32_t address) = 0; + /// read a 8-byte integer virtual void readQuad(const uint32_t address, uint64_t & value) = 0; + /// write a 8-byte integer virtual void writeQuad(const uint32_t address, const uint64_t value) = 0; - + + /// read a 4-byte integer virtual uint32_t readDWord(const uint32_t address) = 0; + /// read a 4-byte integer virtual void readDWord(const uint32_t address, uint32_t & value) = 0; + /// write a 4-byte integer virtual void writeDWord(const uint32_t address, const uint32_t value) = 0; - + + /// read a float virtual float readFloat(const uint32_t address) = 0; + /// write a float virtual void readFloat(const uint32_t address, float & value) = 0; - + + /// read a 2-byte integer virtual uint16_t readWord(const uint32_t address) = 0; + /// read a 2-byte integer virtual void readWord(const uint32_t address, uint16_t & value) = 0; + /// write a 2-byte integer virtual void writeWord(const uint32_t address, const uint16_t value) = 0; - + + /// read a byte virtual uint8_t readByte(const uint32_t address) = 0; + /// read a byte virtual void readByte(const uint32_t address, uint8_t & value) = 0; + /// write a byte virtual void writeByte(const uint32_t address, const uint8_t value) = 0; - + + /// read an arbitrary amount of bytes virtual void read( uint32_t address, uint32_t length, uint8_t* buffer) = 0; + /// write an arbitrary amount of bytes virtual void write(uint32_t address, uint32_t length, uint8_t* buffer) = 0; - - // read a string + + /// read an STL string virtual const string readSTLString (uint32_t offset) = 0; + /// read an STL string virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0; + /// write an STL string virtual void writeSTLString(const uint32_t address, const std::string writeString) = 0; - // get class name of an object with rtti/type info + /// get class name of an object with rtti/type info virtual string readClassName(uint32_t vptr) = 0; - + + /// read a null-terminated C string virtual const std::string readCString (uint32_t offset) = 0; - + + /// @return true if the process is suspended virtual bool isSuspended() = 0; + /// @return true if the process is attached virtual bool isAttached() = 0; + /// @return true if the process is identified -- has a Memory.xml entry virtual bool isIdentified() = 0; - - // find the thread IDs of the process + + /// find the thread IDs of the process virtual bool getThreadIDs(vector & threads ) = 0; - // get virtual memory ranges of the process (what is mapped where) + /// get virtual memory ranges of the process (what is mapped where) virtual void getMemRanges( vector & ranges ) = 0; - - // get the flattened Memory.xml entry of this process + + /// get the flattened Memory.xml entry of this process virtual memory_info *getDescriptor() = 0; - // get the DF Process ID + /// get the DF Process ID virtual int getPID() = 0; - // get module index by name and version. bool 1 = error + /// get module index by name and version. bool 1 = error virtual bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) = 0; - // get the SHM start if available + /// get the SHM start if available virtual char * getSHMStart (void) = 0; - // set a SHM command and wait for a response, return 0 on error or throw exception + /// set a SHM command and wait for a response, return 0 on error or throw exception virtual bool SetAndWait (uint32_t state) = 0; }; + //////////////////////////////////////////////////////////////////////////// + // Compiler appeasement area. Not worth a look really... // + //////////////////////////////////////////////////////////////////////////// + class DFHACK_EXPORT NormalProcess : virtual public Process { friend class ProcessEnumerator; class Private; private: Private * const d; - public: NormalProcess(uint32_t pid, vector & known_versions); ~NormalProcess(); diff --git a/library/include/dfhack/DFProcessEnumerator.h b/library/include/dfhack/DFProcessEnumerator.h index 4e618ae27..0422367d5 100644 --- a/library/include/dfhack/DFProcessEnumerator.h +++ b/library/include/dfhack/DFProcessEnumerator.h @@ -33,35 +33,99 @@ namespace DFHack class memory_info; class Process; class BadProcesses; - /* - * Process manager + /** + * Process enumerator + * Used to enumerate, create and destroy Processes. + * @see DFHack::Process */ class DFHACK_EXPORT ProcessEnumerator { class Private; Private * const d; public: + /** + * Constructs the ProcessEnumerator. + * @param path_to_xml the path to the file that defines memory offsets. (Memory.xml) + */ ProcessEnumerator( string path_to_xml ); + + /** + * Destroys the ProcessEnumerator. + */ ~ProcessEnumerator(); + + /** + * Refresh the internal list of valid Process objects. + * @param invalidated_processes pointer to a BadProcesses object. Not required. All processes are automatically destroyed if the object is not provided. + * @see DFHack::BadProcesses + * @return true if there's at least one valit Process + */ bool Refresh(BadProcesses * invalidated_processes = 0); - bool findProcessess(); + + /** + * @return Number of tracked processes + */ uint32_t size(); + + /** + * Get a Process by index + * @param index index of the Process to be returned + * @return pointer to a Process. 0 if the index is out of range. + */ Process * operator[](uint32_t index); + + /** + * Destroy all tracked Process objects + * Normally called during object destruction. Calling this from outside ProcessManager is nasty. + */ void purge(void); }; + + /** + * Class used for holding a set of invalidated Process objects temporarily and destroy them safely. + * @see DFHack::Process + */ class DFHACK_EXPORT BadProcesses { class Private; Private * const d; void push_back(Process * p); friend class ProcessEnumerator; + void clear(); public: BadProcesses(); + /** + * Destructor. + * All Processes tracked by the BadProcesses object will be destroyed also. + */ ~BadProcesses(); + + /** + * Test if a Process is among the invalidated Processes + * @param p pointer to a Process to be checked + * @return true if the Process is among the invalidated. false otherwise. + */ bool Contains(Process* p); + + /** + * Remove a Process from the tracked invalidated Processes. Used by BadContexts. + * @param p pointer to a Process to be excised + * @see DFHack::BadContexts + * @return true if the Process was among the invalidated. false otherwise. + */ bool excise (Process* p); + + /** + * Get the number of tracked invalid contexts. + * @return Number of tracked invalid contexts + */ uint32_t size(); - void clear(); + + /** + * Get an invalid Process by index + * @param index index of the invalid Process to be returned + * @return pointer to an invalid Process + */ Process * operator[](uint32_t index); }; } diff --git a/library/include/dfhack/modules/Maps.h b/library/include/dfhack/modules/Maps.h index cfdb31d43..6c4dd63a3 100644 --- a/library/include/dfhack/modules/Maps.h +++ b/library/include/dfhack/modules/Maps.h @@ -11,7 +11,7 @@ namespace DFHack /*************************************************************************** T Y P E S ***************************************************************************/ - + enum e_feature { feature_Other, @@ -19,6 +19,7 @@ namespace DFHack feature_Underworld, feature_Hell_Temple }; + static const char * sa_feature[]= { (char*)"Other", @@ -26,6 +27,8 @@ namespace DFHack (char*)"Underworld", (char*)"Hell Temple" }; + + /// used as a key for the local feature map. combines X an Y coords. union planecoord { uint32_t xy; @@ -40,40 +43,60 @@ namespace DFHack return false; } }; + struct t_feature { e_feature type; + /// main material type - decides between stuff like bodily fluids, inorganics, vomit, amber, etc. int16_t main_material; + /// generally some index to a vector of material types. int32_t sub_material; - bool discovered; // placeholder. + /// placeholder + bool discovered; + /// this is NOT part of the DF feature, but an address of the feature as seen by DFhack. uint32_t origin; }; - + + /// mineral vein object struct t_vein { uint32_t vtable; + /// index into the inorganic material vector int32_t type; - int16_t assignment[16]; + /// 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; - uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack. + /// 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 + + /// stores what tiles should appear when the ice melts struct t_frozenliquidvein { uint32_t vtable; + /// a 16x16 array of the original tile types int16_t tiles[16][16]; - uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack. + /// this is NOT part of the DF vein, but an address of the vein as seen by DFhack. + uint32_t address_of; }; - + + /// a 'spattervein' defines what coverings the individual map tiles have (snow, blood, etc) + /// @see PrintSplatterType in DFMiscUtils.h -- incomplete, but illustrative struct t_spattervein { uint32_t vtable; + /// generic material. uint16_t mat1; uint16_t unk1; + /// material vector index uint32_t mat2; + /// something even more specific? uint16_t mat3; + /// 16x16 array of covering 'intensity' uint8_t intensity[16][16]; - uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack. + /// this is NOT part of the DF vein, but an address of the vein as seen by DFhack. + uint32_t address_of; }; enum BiomeOffset @@ -98,16 +121,25 @@ namespace DFHack traffic_restricted }; + /// type of a designation for a tile enum e_designation { + /// no designation designation_no, - designation_default, // dig walls, remove stairs and ramps, gather plants, fell trees - designation_ud_stair, // dig up/down stairs - designation_channel, // dig a channel - designation_ramp, // dig ramp out of a wall - designation_d_stair, // dig a stair down - designation_u_stair, // dig a stair up - designation_7 // whatever + /// dig walls, remove stairs and ramps, gather plants, fell trees. depends on tile type + designation_default, + /// dig up/down stairs + designation_ud_stair, + /// dig a channel + designation_channel, + /// dig ramp out of a wall + designation_ramp, + /// dig a stair down + designation_d_stair, + /// dig a stair up + designation_u_stair, + /// whatever. for completenes I guess + designation_7 }; enum e_liquidtype @@ -120,41 +152,43 @@ namespace DFHack { unsigned int flow_size : 3; // how much liquid is here? unsigned int pile : 1; // stockpile? - /* - * All the different dig designations... needs more info, probably an enum - */ + /// All the different dig designations e_designation dig : 3; unsigned int smooth : 2; unsigned int hidden : 1; - /* + /** * This one is rather involved, but necessary to retrieve the base layer matgloss index - * see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284 for details + * @see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284 */ unsigned int geolayer_index :4; unsigned int light : 1; unsigned int subterranean : 1; // never seen the light of day? unsigned int skyview : 1; // sky is visible now, it rains in here when it rains - /* + /** * Probably similar to the geolayer_index. Only with a different set of offsets and different data. * we don't use this yet */ unsigned int biome : 4; - /* + /** * 0 = water * 1 = magma */ e_liquidtype liquid_type : 1; unsigned int water_table : 1; // srsly. wtf? unsigned int rained : 1; // does this mean actual rain (as in the blue blocks) or a wet tile? - e_traffic traffic : 2; // needs enum - unsigned int flow_forbid : 1; // what? + e_traffic traffic : 2; + /// the tile is not evaluated when calculating flows? + unsigned int flow_forbid : 1; + /// no liquid spreading unsigned int liquid_static : 1; - unsigned int feature_local : 1; // this tile is a part of a feature - unsigned int feature_global : 1; // this tile is a part of a feature - unsigned int liquid_character : 2; // those ripples on streams? - + /// this tile is a part of a local feature. can be combined with 'featstone' tiles + unsigned int feature_local : 1; + /// this tile is a part of a global feature. can be combined with 'featstone' tiles + unsigned int feature_global : 1; + /// those ripples on streams? + unsigned int liquid_character : 2; }; union t_designation @@ -166,12 +200,16 @@ namespace DFHack // occupancy flags (rat,dwarf,horse,built wall,not build wall,etc) struct naked_occupancy { - unsigned int building : 3;// building type... should be an enum? + // building type... should be an enum? // 7 = door + unsigned int building : 3; + /// the tile contains a standing? creature unsigned int unit : 1; + /// the tile contains a prone creature unsigned int unit_grounded : 1; + /// the tile contains an item unsigned int item : 1; - // splatter. everyone loves splatter. + /// splatter. everyone loves splatter. this doesn't seem to be used anymore unsigned int mud : 1; unsigned int vomit :1; unsigned int broken_arrows_color :4; @@ -199,12 +237,14 @@ namespace DFHack struct naked_occupancy_grouped { - unsigned int building : 3;// building type... should be an enum? - // 7 = door + unsigned int building : 3; + /// the tile contains a standing? creature unsigned int unit : 1; + /// the tile contains a prone creature unsigned int unit_grounded : 1; + /// the tile contains an item unsigned int item : 1; - // splatter. everyone loves splatter. + /// splatter. everyone loves splatter. this doesn't seem to be used anymore unsigned int splatter : 26; }; @@ -218,12 +258,15 @@ namespace DFHack // map block flags struct naked_blockflags { - unsigned int designated : 1;// designated for jobs (digging and stuff like that) - unsigned int unk_1 : 1; // possibly related to the designated flag - // two flags required for liquid flow. no idea why + /// designated for jobs (digging and stuff like that) + unsigned int designated : 1; + /// possibly related to the designated flag + unsigned int unk_1 : 1; + /// two flags required for liquid flow. unsigned int liquid_1 : 1; unsigned int liquid_2 : 1; - unsigned int unk_2: 28; // rest of the flags is completely unknown + /// 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 }; @@ -241,13 +284,20 @@ namespace DFHack typedef struct { + /// type of the tiles tiletypes40d tiletypes; + /// flags determining the state of the tiles designations40d designation; + /// flags determining what's on the tiles occupancies40d occupancy; + /// values used for geology/biome assignment biome_indices40d biome_indices; - uint32_t origin; // the address where it came from + /// the address where the block came from + uint32_t origin; t_blockflags blockflags; + /// index into the global feature vector int16_t global_feature; + /// index into the local feature vector... complicated int16_t local_feature; } mapblock40d; @@ -321,6 +371,7 @@ namespace DFHack * Return false/0 on failure, buffer allocated by client app, 256 items long */ bool isValidBlock(uint32_t blockx, uint32_t blocky, uint32_t blockz); + /** * Get the address of a block or 0 if block is not valid */ @@ -340,7 +391,7 @@ namespace DFHack /// read/write temperatures bool ReadTemperatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2); bool WriteTemperatures (uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2); - + /// read/write block occupancies bool ReadOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer); bool WriteOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer); @@ -350,10 +401,8 @@ namespace DFHack bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit); /// read/write the block flags - bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, - t_blockflags &blockflags); - bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, - t_blockflags blockflags); + bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags &blockflags); + bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags blockflags); /// read/write features bool ReadFeatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t & local, int16_t & global); bool WriteLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1); @@ -368,7 +417,7 @@ namespace DFHack std::vector* veins, std::vector* ices = 0, std::vector* splatter = 0); - + private: struct Private; Private *d; diff --git a/library/include/dfhack/DFMemInfoManager.h b/library/private/DFMemInfoManager.h similarity index 95% rename from library/include/dfhack/DFMemInfoManager.h rename to library/private/DFMemInfoManager.h index 99c34afe1..2e11ca608 100644 --- a/library/include/dfhack/DFMemInfoManager.h +++ b/library/private/DFMemInfoManager.h @@ -25,10 +25,12 @@ distribution. #ifndef MEMINFO_MANAGER_H_INCLUDED #define MEMINFO_MANAGER_H_INCLUDED -#include "DFPragma.h" +#include "dfhack/DFPragma.h" +class TiXmlElement; namespace DFHack { + class memory_info; class MemInfoManager { friend class ProcessEnumerator; diff --git a/tools/playground/incrementalsearch.cpp b/tools/playground/incrementalsearch.cpp index cc047466c..c90948c72 100644 --- a/tools/playground/incrementalsearch.cpp +++ b/tools/playground/incrementalsearch.cpp @@ -19,16 +19,125 @@ using namespace std; #endif #include +class SegmentedFinder; +class SegmentFinder +{ + public: + SegmentFinder(DFHack::t_memrange & mr, DFHack::Context * DF) + { + _DF = DF; + mr_ = mr; + mr_.buffer = (uint8_t *)malloc (mr_.end - mr_.start); + DF->ReadRaw(mr_.start,(mr_.end - mr_.start),mr_.buffer); + } + ~SegmentFinder() + { + delete mr_.buffer; + } + template + bool Find (T needle, const uint8_t increment ,vector &found, vector &newfound, P oper) + { + if(found.empty()) + { + //loop + for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(T); offset += increment) + { + if( (*(T *)(mr_.buffer + offset)) == needle) + newfound.push_back(mr_.start + offset); + } + } + else + { + for( uint64_t i = 0; i < found.size(); i++) + { + if(mr_.isInRange(found[i])) + { + uint64_t corrected = found[i] - mr_.start; + if( oper((T *)(mr_.buffer + corrected), needle) ) + newfound.push_back(found[i]); + } + } + } + return true; + } + private: + friend class SegmentedFinder; + DFHack::Context * _DF; + DFHack::t_memrange mr_; +}; + +class SegmentedFinder +{ + public: + SegmentedFinder(vector & ranges, DFHack::Context * DF) + { + _DF = DF; + for(int i = 0; i < ranges.size(); i++) + { + segments.push_back(new SegmentFinder(ranges[i], DF)); + } + } + ~SegmentedFinder() + { + for(int i = 0; i < segments.size(); i++) + { + delete segments[i]; + } + } + SegmentFinder * getSegmentForAddress (uint64_t addr) + { + for(int i = 0; i < segments.size(); i++) + { + if(segments[i]->mr_.isInRange(addr)) + { + return segments[i]; + } + } + } + template + bool Find (const T dword, const uint8_t increment, vector &found, vector &newfound, P oper) + { + newfound.clear(); + for(int i = 0; i < segments.size(); i++) + { + segments[i]->Find(dword, increment, found, newfound, oper); + } + found.clear(); + found = newfound; + return !(found.empty()); + } + private: + DFHack::Context * _DF; + vector segments; +}; + +template +bool equalityP (T *x, T y) +{ + return (*x) == y; +} + +typedef struct +{ + uint32_t start; + uint32_t finish; + uint32_t alloc_finish; +} vecTriplet; + +template +bool vectorLength (T *x, T y) +{ + return (*x) == y; +} //TODO: lots of optimization void searchLoop(DFHack::ContextManager & DFMgr, vector & ranges, int size, int alignment) { - int32_t test1; - int32_t test2; - vector found; - vector newfound; - found.reserve(100000); - newfound.reserve(100000); + uint32_t test1; + vector found; + vector newfound; + found.reserve(100); + newfound.reserve(100); //bool initial = 1; cout << "search ready - insert integers, 'p' for results" << endl; string select; @@ -50,53 +159,45 @@ void searchLoop(DFHack::ContextManager & DFMgr, vector & ran DFMgr.Refresh(); DFHack::Context * DF = DFMgr.getSingleContext(); DF->Attach(); - - newfound.clear(); - bool initial = found.empty(); - if(initial) + SegmentedFinder sf(ranges,DF); + switch(size) { - // for each range - for (int i = 0; i < ranges.size();i++) - { - // can't read? range is invalid to us - if(!ranges[i].read) - continue; - //loop - for(uint64_t offset = ranges[i].start;offset <= ranges[i].end - size; offset+=alignment) - { - DF->ReadRaw(offset, size, (uint8_t *) &test2); - if(test1 == test2 ) - found.push_back(offset); - } - } - cout << "found " << found.size() << " addresses" << endl; + case 1: + sf.Find(test1,alignment,found,newfound, equalityP); + break; + case 2: + sf.Find(test1,alignment,found,newfound, equalityP); + break; + case 4: + sf.Find(test1,alignment,found,newfound, equalityP); + break; } - else + if( found.size() == 1) { - for(int j = 0; j < found.size();j++) - { - DF->ReadRaw(found[j], size, (uint8_t *) &test2); - if(test1 == test2) - { - newfound.push_back(found[j]); - } - } - cout << "matched " << newfound.size() << " addresses out of " << found.size() << endl; - found = newfound; + cout << "Found an address!" << endl; + cout << hex << "0x" << found[0] << endl; } + else + cout << "Found " << dec << found.size() << " addresses." << endl; DF->Detach(); } else break; } } -typedef struct +/* +class VecVerifyPredicate { - uint32_t start; - uint32_t finish; - uint32_t alloc_finish; -} vecTriplet; - + public: + VecVerifyPredicate(){} + bool operator()(vecTriplet * vt, uint64_t length) + { + if(vt.start <= vt.finish && vt.finish <= vt.alloc_finish) + return true; + return false; + } +}; +*/ void searchLoopVector(DFHack::ContextManager & DFMgr, vector & ranges, uint32_t element_size) { vecTriplet load; @@ -190,7 +291,10 @@ void mkcopy(DFHack::ContextManager & DFMgr, vector & ranges, DF->Detach(); DFMgr.purge(); } - +inline void printRange(DFHack::t_memrange * tpr) +{ + std::cout << std::hex << tpr->start << " - " << tpr->end << "|" << (tpr->read ? "r" : "-") << (tpr->write ? "w" : "-") << (tpr->execute ? "x" : "-") << "|" << tpr->name << std::endl; +} int main (void) { string select; @@ -216,7 +320,7 @@ int main (void) for(int i = 0; i< ranges.size();i++) { cout << dec << "(" << i << ") "; - ranges[i].print(); + printRange(&(ranges[i])); } try_again_ranges: @@ -258,7 +362,7 @@ int main (void) selected_ranges.insert(selected_ranges.begin(),ranges.begin() + start, ranges.begin() + end); for(int i = 0; i< selected_ranges.size();i++) { - selected_ranges[i].print(); + printRange(&(selected_ranges[i])); } try_again_type: cout << "Select search type: 1=number(default), 2=vector, 3=string" << endl;