From 62fc5bd677ba88f11ab523bee5ee3fbc6cb016be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 7 Apr 2010 22:28:05 +0200 Subject: [PATCH 1/5] Spatter veins, spatterdump tool --- dfhack/include/modules/Maps.h | 22 ++++-- dfhack/modules/Maps.cpp | 17 +++- examples/CMakeLists.txt | 4 + examples/spatterdump.cpp | 141 ++++++++++++++++++++++++++++++++++ examples/veccheck.cpp | 102 ++++++++++++++++++++++-- examples/veinlook.cpp | 4 +- output/Memory.xml | 6 +- tools/prospector.cpp | 3 +- 8 files changed, 282 insertions(+), 17 deletions(-) create mode 100644 examples/spatterdump.cpp diff --git a/dfhack/include/modules/Maps.h b/dfhack/include/modules/Maps.h index 7e4274cc4..d7056921a 100644 --- a/dfhack/include/modules/Maps.h +++ b/dfhack/include/modules/Maps.h @@ -25,6 +25,18 @@ namespace DFHack { uint32_t vtable; 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. + }; + + struct t_spattervein + { + uint32_t vtable; + uint16_t mat1; + uint16_t unk1; + uint32_t mat2; + uint16_t mat3; + 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. }; enum e_traffic @@ -171,15 +183,14 @@ namespace DFHack typedef int16_t tiletypes40d [16][16]; typedef DFHack::t_designation designations40d [16][16]; - typedef DFHack::t_occupancy occupancies40d [16][16]; +// typedef DFHack::t_occupancy occupancies40d [16][16]; typedef uint8_t biome_indices40d [16]; typedef struct { tiletypes40d tiletypes; designations40d designation; - occupancies40d occupancy; - // really a '7', but I use 8 to make it neater :) +// occupancies40d occupancy; biome_indices40d biome_indices; uint32_t origin; // the address where it came from t_blockflags blockflags; @@ -265,10 +276,11 @@ namespace DFHack bool ReadDesignations(uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer); bool WriteDesignations (uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer); + /* /// 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); - +*/ /// read/write the block dirty bit - this is used to mark a map block so that DF scans it for designated jobs like digging bool ReadDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool &dirtybit); bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit); @@ -281,7 +293,7 @@ namespace DFHack bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz, biome_indices40d *buffer); /// read aggregated veins of a block - bool ReadVeins(uint32_t blockx, uint32_t blocky, uint32_t blockz, std::vector & veins, std::vector & ices); + bool ReadVeins(uint32_t blockx, uint32_t blocky, uint32_t blockz, std::vector & veins, std::vector & ices, std::vector & splatter); private: struct Private; diff --git a/dfhack/modules/Maps.cpp b/dfhack/modules/Maps.cpp index 820cf9c6c..6f0a3cd53 100644 --- a/dfhack/modules/Maps.cpp +++ b/dfhack/modules/Maps.cpp @@ -325,7 +325,7 @@ bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices4 // veins of a block, expects empty vein vectors -bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector & veins, vector & ices) +bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector & veins, vector & ices, vector &splatter) { uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; veins.clear(); @@ -344,6 +344,7 @@ bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector & veins { t_vein v; t_frozenliquidvein fv; + t_spattervein sv; // read the vein pointer from the vector uint32_t temp = * (uint32_t *) p_veins[i]; @@ -361,9 +362,18 @@ try_again: { // read the ice vein data (dereference pointer) g_pProcess->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) + { + // read the splatter vein data (dereference pointer) + g_pProcess->read (temp, sizeof(t_spattervein), (uint8_t *) &sv); + sv.address_of = temp; + // store it in the vector + splatter.push_back (sv); + } else if(g_pProcess->readClassName(type) == "block_square_event_frozen_liquid") { off.vein_ice_vptr = type; @@ -374,6 +384,11 @@ try_again: off.vein_mineral_vptr = type; goto try_again; } + else if(g_pProcess->readClassName(type) == "block_square_event_material_spatter") + { + off.vein_spatter_vptr = type; + goto try_again; + } } return true; } diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7ec11cc62..226eafc97 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -61,6 +61,10 @@ TARGET_LINK_LIBRARIES(dfvecc dfhack) ADD_EXECUTABLE(dftreedump treedump.cpp) TARGET_LINK_LIBRARIES(dftreedump dfhack) +# spatterdump - dump spatter 'veins' +ADD_EXECUTABLE(dfspatterdump spatterdump.cpp) +TARGET_LINK_LIBRARIES(dfspatterdump dfhack) + # catsplosion - Makes every cat pregnant, and almost due... # Author: Zhentar # ADD_EXECUTABLE(dfcatsplosion catsplosion.cpp) diff --git a/examples/spatterdump.cpp b/examples/spatterdump.cpp new file mode 100644 index 000000000..e0d365073 --- /dev/null +++ b/examples/spatterdump.cpp @@ -0,0 +1,141 @@ +// Just show some position data + +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "miscutils.h" + +using namespace DFHack; + +char shades[10] = {'#','$','O','=','+','|','-','^','.',' '}; +int main (int numargs, const char ** args) +{ + uint32_t addr; + uint32_t x_max,y_max,z_max; + vector veinVector; + vector IceVeinVector; + vector splatter; + + DFHack::API DF("Memory.xml"); + try + { + DF.Attach(); + } + catch (exception& e) + { + cerr << e.what() << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + + DFHack::Maps *Maps =DF.getMaps(); + DFHack::Position *Pos =DF.getPosition(); + // init the map + if(!Maps->Start()) + { + cerr << "Can't init map." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + int32_t cx, cy, cz; + Maps->getSize(x_max,y_max,z_max); + Pos->getCursorCoords(cx,cy,cz); + if(cx == -30000) + { + // walk the map + for(uint32_t x = 0; x< x_max;x++) for(uint32_t y = 0; y< y_max;y++) for(uint32_t z = 0; z< z_max;z++) + { + if(Maps->isValidBlock(x,y,z)) + { + // look for splater veins + Maps->ReadVeins(x,y,z,veinVector,IceVeinVector,splatter); + if(splatter.size()) + { + printf("Block %d/%d/%d\n",x,y,z); + + for(int i = 0; i < splatter.size(); i++) + { + printf("Splatter %d\nmat1: %d\nunknown: %d\nmat2: %d\nmat3: %d\n",i,splatter[i].mat1,splatter[i].unk1,splatter[i].mat2,splatter[i].mat3); + for(uint32_t yyy = 0; yyy < 16; yyy++) + { + cout << "|"; + for(uint32_t xxx = 0; xxx < 16; xxx++) + { + uint8_t intensity = splatter[i].intensity[xxx][yyy]; + cout << shades[9 - (intensity / 28)]; + } + cout << "|" << endl; + } + + hexdump(DF, splatter[i].address_of,20); + cout << endl; + } + } + } + } + } + else + { + uint32_t bx,by,bz; + bx = cx / 16; + by = cy / 16; + bz = cz; + // look for splater veins + Maps->ReadVeins(bx,by,bz,veinVector,IceVeinVector,splatter); + if(splatter.size()) + { + printf("Block %d/%d/%d\n",bx,by,bz); + + for(int i = 0; i < splatter.size(); i++) + { + printf("Splatter %d\nmat1: %d\nunknown: %d\nmat2: %d\nmat3: %d\n",i,splatter[i].mat1,splatter[i].unk1,splatter[i].mat2,splatter[i].mat3); + for(uint32_t y = 0; y < 16; y++) + { + cout << "|"; + for(uint32_t x = 0; x < 16; x++) + { + uint8_t intensity = splatter[i].intensity[x][y]; + if(intensity) + { + cout << "#"; + } + else + { + cout << " "; + } + } + cout << "|" << endl; + } + + hexdump(DF, splatter[i].address_of,20); + cout << endl; + } + } + } + #ifndef LINUX_BUILD + cout << "Done. Press any key to continue" << endl; + cin.ignore(); + #endif + return 0; +} diff --git a/examples/veccheck.cpp b/examples/veccheck.cpp index 93452467f..e0d365073 100644 --- a/examples/veccheck.cpp +++ b/examples/veccheck.cpp @@ -19,16 +19,20 @@ using namespace std; #include #include #include +#include #include "miscutils.h" +using namespace DFHack; + +char shades[10] = {'#','$','O','=','+','|','-','^','.',' '}; int main (int numargs, const char ** args) { uint32_t addr; - if (numargs == 2) - { - istringstream input (args[1],istringstream::in); - input >> std::hex >> addr; - } + uint32_t x_max,y_max,z_max; + vector veinVector; + vector IceVeinVector; + vector splatter; + DFHack::API DF("Memory.xml"); try { @@ -42,7 +46,93 @@ int main (int numargs, const char ** args) #endif return 1; } - + + DFHack::Maps *Maps =DF.getMaps(); + DFHack::Position *Pos =DF.getPosition(); + // init the map + if(!Maps->Start()) + { + cerr << "Can't init map." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + int32_t cx, cy, cz; + Maps->getSize(x_max,y_max,z_max); + Pos->getCursorCoords(cx,cy,cz); + if(cx == -30000) + { + // walk the map + for(uint32_t x = 0; x< x_max;x++) for(uint32_t y = 0; y< y_max;y++) for(uint32_t z = 0; z< z_max;z++) + { + if(Maps->isValidBlock(x,y,z)) + { + // look for splater veins + Maps->ReadVeins(x,y,z,veinVector,IceVeinVector,splatter); + if(splatter.size()) + { + printf("Block %d/%d/%d\n",x,y,z); + + for(int i = 0; i < splatter.size(); i++) + { + printf("Splatter %d\nmat1: %d\nunknown: %d\nmat2: %d\nmat3: %d\n",i,splatter[i].mat1,splatter[i].unk1,splatter[i].mat2,splatter[i].mat3); + for(uint32_t yyy = 0; yyy < 16; yyy++) + { + cout << "|"; + for(uint32_t xxx = 0; xxx < 16; xxx++) + { + uint8_t intensity = splatter[i].intensity[xxx][yyy]; + cout << shades[9 - (intensity / 28)]; + } + cout << "|" << endl; + } + + hexdump(DF, splatter[i].address_of,20); + cout << endl; + } + } + } + } + } + else + { + uint32_t bx,by,bz; + bx = cx / 16; + by = cy / 16; + bz = cz; + // look for splater veins + Maps->ReadVeins(bx,by,bz,veinVector,IceVeinVector,splatter); + if(splatter.size()) + { + printf("Block %d/%d/%d\n",bx,by,bz); + + for(int i = 0; i < splatter.size(); i++) + { + printf("Splatter %d\nmat1: %d\nunknown: %d\nmat2: %d\nmat3: %d\n",i,splatter[i].mat1,splatter[i].unk1,splatter[i].mat2,splatter[i].mat3); + for(uint32_t y = 0; y < 16; y++) + { + cout << "|"; + for(uint32_t x = 0; x < 16; x++) + { + uint8_t intensity = splatter[i].intensity[x][y]; + if(intensity) + { + cout << "#"; + } + else + { + cout << " "; + } + } + cout << "|" << endl; + } + + hexdump(DF, splatter[i].address_of,20); + cout << endl; + } + } + } #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); diff --git a/examples/veinlook.cpp b/examples/veinlook.cpp index b22723fa5..ddd2da577 100644 --- a/examples/veinlook.cpp +++ b/examples/veinlook.cpp @@ -311,6 +311,7 @@ main(int argc, char *argv[]) vector< vector > layerassign; vector veinVector; vector IceVeinVector; + vector splatter; DFHack::Materials * Mats = 0; DFHack::Maps * Maps = 0; @@ -444,6 +445,7 @@ main(int argc, char *argv[]) veinVector.clear(); IceVeinVector.clear(); effects.clear(); + splatter.clear(); dirtybit = 0; // Supend, read/write data @@ -473,7 +475,7 @@ main(int argc, char *argv[]) if(i == 0 && j == 0) { // read veins - Maps->ReadVeins(cursorX+i,cursorY+j,cursorZ,veinVector,IceVeinVector); + Maps->ReadVeins(cursorX+i,cursorY+j,cursorZ,veinVector,IceVeinVector,splatter); // get pointer to block blockaddr = Maps->getBlockPtr(cursorX+i,cursorY+j,cursorZ); diff --git a/output/Memory.xml b/output/Memory.xml index 9eac342f3..f7c49b8df 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1358,15 +1358,15 @@ 55 56 57 + 58 + 59 60 + 61 62 63 64 65 66 - 58 - 59 - 61 67 68 69 diff --git a/tools/prospector.cpp b/tools/prospector.cpp index f944638dc..f75cedd96 100644 --- a/tools/prospector.cpp +++ b/tools/prospector.cpp @@ -110,6 +110,7 @@ int main (int argc, const char* argv[]) int16_t tempvein [16][16]; vector veins; vector iceveins; + vector splatter; uint32_t maximum_regionoffset = 0; uint32_t num_overflows = 0; // walk the map! @@ -128,7 +129,7 @@ int main (int argc, const char* argv[]) memset(tempvein, -1, sizeof(tempvein)); veins.clear(); - Maps->ReadVeins(x,y,z,veins,iceveins); + Maps->ReadVeins(x,y,z,veins,iceveins,splatter); if(showbaselayers) { From 13571a9bde6ceed66a35550faea69fc26813c68d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 7 Apr 2010 23:56:23 +0200 Subject: [PATCH 2/5] *VERY* Specific Blood --- examples/spatterdump.cpp | 87 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/examples/spatterdump.cpp b/examples/spatterdump.cpp index e0d365073..ad3498259 100644 --- a/examples/spatterdump.cpp +++ b/examples/spatterdump.cpp @@ -24,6 +24,81 @@ using namespace std; using namespace DFHack; +void PrintSplatterType (int16_t mat1, int32_t mat2, vector creature_types) +{ + switch (mat1) + { + case 0: + cout <<"Rock"; + break; + case 1: + cout <<"Amber"; + break; + case 2: + cout <<"Coral"; + break; + case 3: + cout <<"Green Glass"; + break; + case 4: + cout <<"Clear Glass"; + break; + case 5: + cout <<"Crystal Glass"; + break; + case 6: + cout <<"Ice"; + break; + case 7: + cout <<"Coal"; + break; + case 8: + cout <<"Potash"; + break; + case 9: + cout <<"Ash"; + break; + case 10: + cout <<"Pearlash"; + break; + case 11: + cout <<"Lye"; + break; + case 12: + cout <<"Mud"; + break; + case 13: + cout <<"Vomit"; + break; + case 14: + cout <<"Salt"; + break; + case 15: + cout <<"Filth"; + break; + case 16: + cout <<"Frozen? Filth"; + break; + case 18: + cout <<"Grime"; + break; + case 0xF2: + cout << "Very Specific Blood (references a named creature)"; + break; + case 0x2A: + case 0x2B: + if(mat2 != -1) + { + cout << creature_types[mat2].id << " "; + } + cout<<"Blood"; + break; + default: + cout <<"Unknown"; + break; + } +} + char shades[10] = {'#','$','O','=','+','|','-','^','.',' '}; int main (int numargs, const char ** args) { @@ -49,6 +124,11 @@ int main (int numargs, const char ** args) DFHack::Maps *Maps =DF.getMaps(); DFHack::Position *Pos =DF.getPosition(); + DFHack::Materials *Mats =DF.getMaterials(); + vector creature_types; + + Mats->ReadCreatureTypes(creature_types); + // init the map if(!Maps->Start()) { @@ -58,6 +138,7 @@ int main (int numargs, const char ** args) #endif return 1; } + int32_t cx, cy, cz; Maps->getSize(x_max,y_max,z_max); Pos->getCursorCoords(cx,cy,cz); @@ -77,6 +158,9 @@ int main (int numargs, const char ** args) for(int i = 0; i < splatter.size(); i++) { printf("Splatter %d\nmat1: %d\nunknown: %d\nmat2: %d\nmat3: %d\n",i,splatter[i].mat1,splatter[i].unk1,splatter[i].mat2,splatter[i].mat3); + PrintSplatterType(splatter[i].mat1,splatter[i].mat2,creature_types); + cout << endl; + printf("Address 0x%08x\n",splatter[i].address_of); for(uint32_t yyy = 0; yyy < 16; yyy++) { cout << "|"; @@ -110,6 +194,9 @@ int main (int numargs, const char ** args) for(int i = 0; i < splatter.size(); i++) { printf("Splatter %d\nmat1: %d\nunknown: %d\nmat2: %d\nmat3: %d\n",i,splatter[i].mat1,splatter[i].unk1,splatter[i].mat2,splatter[i].mat3); + PrintSplatterType(splatter[i].mat1,splatter[i].mat2,creature_types); + cout << endl; + printf("Address 0x%08x\n",splatter[i].address_of); for(uint32_t y = 0; y < 16; y++) { cout << "|"; From 659e57e3c424237095ef3300eceb5b57a58cb02a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 8 Apr 2010 02:20:54 +0200 Subject: [PATCH 3/5] Added missing file, small changes --- dfhack/include/DFTypes.h | 43 +++--------- examples/miscutils.h | 137 +++++++++++++++++++++++++++++++++++++++ output/Memory.xml | 2 + 3 files changed, 147 insertions(+), 35 deletions(-) create mode 100644 examples/miscutils.h diff --git a/dfhack/include/DFTypes.h b/dfhack/include/DFTypes.h index f9d19c0dc..2afd1f4f5 100644 --- a/dfhack/include/DFTypes.h +++ b/dfhack/include/DFTypes.h @@ -31,41 +31,6 @@ distribution. namespace DFHack { -template -struct junk_fill -{ - uint8_t data[SIZE]; - /* - void Dump() - { - cout< +struct junk_fill +{ + uint8_t data[SIZE]; +}; + enum EFFECT_TYPE { EFF_MIASMA=0, @@ -88,6 +60,7 @@ enum EFFECT_TYPE EFF_BOILING, // uses matgloss EFF_OCEANWAVE }; + struct t_effect_df40d //size 40 { uint16_t type; diff --git a/examples/miscutils.h b/examples/miscutils.h new file mode 100644 index 000000000..b1cf49fcb --- /dev/null +++ b/examples/miscutils.h @@ -0,0 +1,137 @@ +#ifndef DF_MISCUTILS +#define DF_MISCUTILS +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr) +{ + cout << "----==== " << name << " ====----" << endl; + DFHack::DfVector vect(p,addr,4); + for(int i = 0; i < vect.getSize();i++) + { + uint32_t addr = *(uint32_t *) vect[i]; + cout << p->readSTLString(addr) << endl; + } + cout << endl; +} +void DumpObjVtables (const char * name, DFHack::Process *p, uint32_t addr) +{ + cout << "----==== " << name << " ====----" << endl; + DFHack::DfVector vect(p,addr,4); + for(int i = 0; i < vect.getSize();i++) + { + uint32_t addr = *(uint32_t *) vect[i]; + uint32_t vptr = p->readDWord(addr); + cout << p->readClassName(vptr) << endl; + } + cout << endl; +} +void DumpDWordVector (const char * name, DFHack::Process *p, uint32_t addr) +{ + cout << "----==== " << name << " ====----" << endl; + DFHack::DfVector vect(p,addr,4); + for(int i = 0; i < vect.getSize();i++) + { + uint32_t number = *(uint32_t *) vect[i]; + cout << number << endl; + } + cout << endl; +} + +/* +address = absolute address of dump start +length = length in lines. 1 line = 16 bytes +*/ +void hexdump (DFHack::API& DF, uint32_t address, uint32_t length) +{ + char *buf = new char[length * 16]; + + DF.ReadRaw(address, length * 16, (uint8_t *) buf); + for (int i = 0; i < length; i++) + { + // leading offset + cout << "0x" << hex << setw(8) << address + i*16 << "| "; + // groups + for(int j = 0; j < 4; j++) + { + // bytes + for(int k = 0; k < 4; k++) + { + int idx = i * 16 + j * 4 + k; + + cout << hex << setw(2) << int(static_cast(buf[idx])) << " "; + } + cout << " "; + } + cout << endl; + } + delete buf; +} + +void interleave_hex (DFHack::API& DF, vector < uint32_t > & addresses, uint32_t length) +{ + vector bufs; + + for(int counter = 0; counter < addresses.size(); counter ++) + { + char * buf = new char[length * 16]; + DF.ReadRaw(addresses[counter], length * 16, (uint8_t *) buf); + bufs.push_back(buf); + } + cout << setfill('0'); + + // output a header + cout << "line offset "; + for (int obj = 0; obj < addresses.size(); obj++) + { + cout << "0x" << hex << setw(9) << addresses[obj] << " "; + } + cout << endl; + + for(int offs = 0 ; offs < length * 16; offs += 4) + { + if((!(offs % 16)) && offs != 0) + { + cout << endl; + } + cout << setfill(' '); + cout << dec << setw(4) << offs/4 << " "; + cout << setfill('0'); + cout << "0x" << hex << setw(4) << offs << " "; + for (int object = 0; object < bufs.size(); object++) + { + // bytes + for(int k = 0; k < 4; k++) + { + uint8_t data = bufs[object][offs + k]; + cout << hex << setw(2) << int(static_cast(data)) << " "; + } + cout << " "; + } + cout << endl; + } + for(int counter = 0; counter < addresses.size(); counter ++) + { + delete bufs[counter]; + } +} + +template +void print_bits ( T val, std::ostream& out ) +{ + T n_bits = sizeof ( val ) * CHAR_BIT; + + for ( unsigned i = 0; i < n_bits; ++i ) { + out<< !!( val & 1 ) << " "; + val >>= 1; + } +} + +#endif \ No newline at end of file diff --git a/output/Memory.xml b/output/Memory.xml index f7c49b8df..ce5b5a675 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -3026,6 +3026,8 @@ map_data_1b60_offset 0x1B9c
0x016AFE58
+ -