From 6cce9409011a366458e07961d00b84324f369d05 Mon Sep 17 00:00:00 2001 From: Matthew Cline Date: Sun, 10 Jul 2011 23:50:29 -0700 Subject: [PATCH] buildingsdump.cpp: cleanup Split code off from main into functions for easier readibility, and improved code formatting some. Also, reduced the amount of hex dumped for "buildings under cursor" mode, since any more than that was dumping memory regions that were constantly changing as ticks went by even if nothing was done to the building. --- tools/examples/buildingsdump.cpp | 230 +++++++++++++++++-------------- 1 file changed, 130 insertions(+), 100 deletions(-) diff --git a/tools/examples/buildingsdump.cpp b/tools/examples/buildingsdump.cpp index ef85173af..9dd5fb13e 100644 --- a/tools/examples/buildingsdump.cpp +++ b/tools/examples/buildingsdump.cpp @@ -1,4 +1,4 @@ -// Creature dump +// Building dump #include #include @@ -11,33 +11,118 @@ #define DFHACK_WANT_MISCUTILS #include -int main (int argc,const char* argv[]) +void doWordPerLine(DFHack::Context *DF, DFHack::VersionInfo * mem, + DFHack::Buildings * Bld, uint32_t numBuildings, + const char* type, int lines) { - int lines = 16; - int mode = 0; - if (argc < 2 || argc > 3) + std::cout << numBuildings << std::endl; + std::vector < uint32_t > addresses; + for(uint32_t i = 0; i < numBuildings; i++) { - /* - cout << "usage:" << endl; - cout << argv[0] << " object_name [number of lines]" << endl; - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; - */ + DFHack::t_building temp; + Bld->Read(i, temp); + if(temp.type != 0xFFFFFFFF) // check if type isn't invalid + { + std::string typestr; + mem->resolveClassIDToClassname(temp.type, typestr); + std::cout << typestr << std::endl; + if(typestr == type) + addresses.push_back(temp.origin); + } + else + { + // couldn't translate type, print out the vtable + std::cout << "unknown vtable: " << temp.vtable << std::endl; + } } - else if(argc == 3) + + if (addresses.empty()) { - std::string s = argv[2]; //blah. I don't care + std::cout << "No buildings matching '" << type << "'" << endl; + return; + } + + interleave_hex(DF,addresses,lines / 4); +} + +void doUnderCursor(DFHack::Context *DF, DFHack::VersionInfo * mem, + DFHack::Buildings * Bld, uint32_t numBuildings, + int32_t x, int32_t y, int32_t z) +{ + std::map custom_workshop_types; + Bld->ReadCustomWorkshopTypes(custom_workshop_types); + + uint32_t num_under_cursor = 0; + + for(uint32_t i = 0; i < numBuildings; i++) + { + DFHack::t_building temp; + Bld->Read(i, temp); + if( (uint32_t)x >= temp.x1 + && (uint32_t)x <= temp.x2 + && (uint32_t)y >= temp.y1 + && (uint32_t)y <= temp.y2 + && (uint32_t)z == temp.z + ) + { + num_under_cursor++; + std::string typestr; + mem->resolveClassIDToClassname(temp.type, typestr); + printf("Address 0x%x, type %d (%s), %d/%d/%d\n", temp.origin, + temp.type, typestr.c_str(), temp.x1, temp.y1, temp.z); + printf("Material %d %d\n", temp.material.type, + temp.material.index); + int32_t custom; + if((custom = Bld->GetCustomWorkshopType(temp)) != -1) + { + printf("Custom workshop type %s (%d)\n", + custom_workshop_types[custom].c_str(), custom); + } + hexdump(DF, temp.origin, 34*16); + } + } + + if (num_under_cursor == 0) + std::cout << "No buildings present under cursor." << endl; +} + +void doListAll(DFHack::VersionInfo * mem, DFHack::Buildings * Bld, + uint32_t numBuildings) +{ + std::cout << "Num buildings present: " << numBuildings << std::endl; + for(uint32_t i = 0; i < numBuildings; i++) + { + DFHack::t_building temp; + Bld->Read(i, temp); + std::string typestr; + mem->resolveClassIDToClassname(temp.type, typestr); + printf("Address 0x%x, type %d (%s), Coord %d/%d/%d\n", temp.origin, + temp.type, typestr.c_str(), temp.x1,temp.y1,temp.z); + } +} + +void doFinish(DFHack::Context *DF) +{ + DF->Detach(); + #ifndef LINUX_BUILD + std::cout << "Done. Press any key to continue" << std::endl; + cin.ignore(); + #endif +} + +int main (int argc,const char* argv[]) +{ + int lines = 16; + bool word_per_line = false; + if (argc == 3) + { + std::string num = argv[2]; //blah. I don't care std::istringstream ins; // Declare an input string stream. - ins.str(s); // Specify string to read. + ins.str(num); // Specify string to read. ins >> lines; // Reads the integers from the string. - mode = 1; + word_per_line = true; } - std::map custom_workshop_types; - DFHack::ContextManager DFMgr ("Memory.xml"); DFHack::Context *DF; try @@ -59,91 +144,36 @@ int main (int argc,const char* argv[]) DFHack::Gui * Gui = DF->getGui(); uint32_t numBuildings; - if(Bld->Start(numBuildings)) + if(!Bld->Start(numBuildings)) { - Bld->ReadCustomWorkshopTypes(custom_workshop_types); - if(mode) - { - std::cout << numBuildings << std::endl; - std::vector < uint32_t > addresses; - for(uint32_t i = 0; i < numBuildings; i++) - { - DFHack::t_building temp; - Bld->Read(i, temp); - if(temp.type != 0xFFFFFFFF) // check if type isn't invalid - { - std::string typestr; - mem->resolveClassIDToClassname(temp.type, typestr); - std::cout << typestr << std::endl; - if(typestr == argv[1]) - { - //cout << buildingtypes[temp.type] << " 0x" << hex << temp.origin << endl; - //hexdump(DF, temp.origin, 256); - addresses.push_back(temp.origin); - } - } - else - { - // couldn't translate type, print out the vtable - std::cout << "unknown vtable: " << temp.vtable << std::endl; - } - } - interleave_hex(DF,addresses,lines / 4); - } - else // mode - { - int32_t x,y,z; - Gui->getCursorCoords(x,y,z); - if(x != -30000) - { - for(uint32_t i = 0; i < numBuildings; i++) - { - DFHack::t_building temp; - Bld->Read(i, temp); - if( (uint32_t)x >= temp.x1 - && (uint32_t)x <= temp.x2 - && (uint32_t)y >= temp.y1 - && (uint32_t)y <= temp.y2 - && (uint32_t)z == temp.z - ) - { - std::string typestr; - mem->resolveClassIDToClassname(temp.type, typestr); - printf("Address 0x%x, type %d (%s), %d/%d/%d\n",temp.origin, temp.type, typestr.c_str(), temp.x1,temp.y1,temp.z); - printf("Material %d %d\n", temp.material.type, temp.material.index); - int32_t custom; - if((custom = Bld->GetCustomWorkshopType(temp)) != -1) - { - printf("Custom workshop type %s (%d)\n",custom_workshop_types[custom].c_str(),custom); - } - hexdump(DF,temp.origin,120*16); - } - } - } - else - { - std::cout << numBuildings << std::endl; - for(uint32_t i = 0; i < numBuildings; i++) - { - DFHack::t_building temp; - Bld->Read(i, temp); - std::string typestr; - mem->resolveClassIDToClassname(temp.type, typestr); - printf("Address 0x%x, type %d (%s), %d/%d/%d\n",temp.origin, temp.type, typestr.c_str(), temp.x1,temp.y1,temp.z); - } - } - } - Bld->Finish(); + std::cerr << "buildings not supported for this DF version" << std::endl; + doFinish(DF); + return 1; } + + if (numBuildings == 0) + { + cout << "No buildings on site." << endl; + doFinish(DF); + return 0; + } + + if (word_per_line) + doWordPerLine(DF, mem, Bld, numBuildings, argv[1], lines); else { - std::cerr << "buildings not supported for this DF version" << std::endl; + int32_t x,y,z; + Gui->getCursorCoords(x,y,z); + + if(x != -30000) + doUnderCursor(DF, mem, Bld, numBuildings, x, y, z); + else + doListAll(mem, Bld, numBuildings); } - DF->Detach(); - #ifndef LINUX_BUILD - std::cout << "Done. Press any key to continue" << std::endl; - cin.ignore(); - #endif + Bld->Finish(); + + doFinish(DF); + return 0; }