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.
develop
Matthew Cline 2011-07-10 23:50:29 -07:00
parent 49fd378a47
commit 6cce940901
1 changed files with 130 additions and 100 deletions

@ -1,4 +1,4 @@
// Creature dump
// Building dump
#include <iostream>
#include <iomanip>
@ -11,59 +11,10 @@
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h>
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)
{
/*
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;
*/
}
else if(argc == 3)
{
std::string s = argv[2]; //blah. I don't care
std::istringstream ins; // Declare an input string stream.
ins.str(s); // Specify string to read.
ins >> lines; // Reads the integers from the string.
mode = 1;
}
std::map <uint32_t, std::string> custom_workshop_types;
DFHack::ContextManager DFMgr ("Memory.xml");
DFHack::Context *DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::VersionInfo * mem = DF->getMemoryInfo();
DFHack::Buildings * Bld = DF->getBuildings();
DFHack::Gui * Gui = DF->getGui();
uint32_t 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++)
@ -75,27 +26,34 @@ int main (int argc,const char* argv[])
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);
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;
}
}
interleave_hex(DF,addresses,lines / 4);
}
else // mode
{
int32_t x,y,z;
Gui->getCursorCoords(x,y,z);
if(x != -30000)
if (addresses.empty())
{
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 <uint32_t, std::string> 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;
@ -107,43 +65,115 @@ int main (int argc,const char* argv[])
&& (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);
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);
printf("Custom workshop type %s (%d)\n",
custom_workshop_types[custom].c_str(), custom);
}
hexdump(DF,temp.origin,120*16);
hexdump(DF, temp.origin, 34*16);
}
}
}
else
{
std::cout << numBuildings << std::endl;
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), %d/%d/%d\n",temp.origin, temp.type, typestr.c_str(), temp.x1,temp.y1,temp.z);
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(num); // Specify string to read.
ins >> lines; // Reads the integers from the string.
word_per_line = true;
}
DFHack::ContextManager DFMgr ("Memory.xml");
DFHack::Context *DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
Bld->Finish();
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
else
DFHack::VersionInfo * mem = DF->getMemoryInfo();
DFHack::Buildings * Bld = DF->getBuildings();
DFHack::Gui * Gui = DF->getGui();
uint32_t numBuildings;
if(!Bld->Start(numBuildings))
{
std::cerr << "buildings not supported for this DF version" << std::endl;
doFinish(DF);
return 1;
}
DF->Detach();
#ifndef LINUX_BUILD
std::cout << "Done. Press any key to continue" << std::endl;
cin.ignore();
#endif
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
{
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);
}
Bld->Finish();
doFinish(DF);
return 0;
}