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,33 +11,118 @@
#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)
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 <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;
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 <uint32_t, std::string> 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;
}