From c2faa074e85da741ee7e4cd5c6cd6e823c8301b6 Mon Sep 17 00:00:00 2001 From: mizipzor Date: Thu, 18 Feb 2010 02:21:23 +0800 Subject: [PATCH 01/17] some improvements to digger --- examples/digger.cpp | 111 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 97 insertions(+), 14 deletions(-) diff --git a/examples/digger.cpp b/examples/digger.cpp index 1a4e8f556..958b7f089 100644 --- a/examples/digger.cpp +++ b/examples/digger.cpp @@ -8,12 +8,14 @@ // TODO add a sort of "sub-target" to dig() to make it able to designate stone as well // TODO add proper cli // TODO add interactive text based menu +// TODO add ability to mark num closest to cursor #include #include #include #include #include +#include using namespace std; #include @@ -31,48 +33,120 @@ int vec_count(vector& vec, uint16_t t) return count; } -int dig(DFHack::API& DF, vector& targets) +// manhattan distance +int source_distance(int sx, int sy, int sz, + int x, int y, int z, int i) { + // TODO changing x and y seems to be optimized away (?) + cout << x << " " << i << " " << i%16 << " " << x+(i%16) << endl; + + // handle the fact that x,y,z refers to a 16x16 grid + //x += i%16; + //y += i/16; + int dx = i%16; + int dy = i/16; + //x *= 16; + //y *= 16; + //x += dx; + //y += dy; + return abs(sx-(x+(i%16)))+abs(sy-(y+(i/16)))+abs(sz-z); +} + +struct DigTarget +{ + int source_distance; // the distance to the source coords, used for sorting + int x, y, z; // call read designations with these and you have the tile at i + int i; // 0 <= i <= 255 + + bool operator<(const DigTarget& o) { return source_distance < o.source_distance; } +}; + +int dig(DFHack::API& DF, + vector& targets, + int num = -1, + const int x_source = 0, + const int y_source = 0, + const int z_source = 0) +{ + if (num == 0) + return 0; // max limit of 0, nothing to do + uint32_t x_max,y_max,z_max; DFHack::t_designation designations[256]; uint16_t tiles[256]; - uint32_t count = 0; + //uint32_t count = 0; DF.getSize(x_max,y_max,z_max); + + // every tile found, will later be sorted by distance to source + vector candidates; // walk the map - for(uint32_t x = 0; x< x_max;x++) + for(uint32_t x = 0; x < x_max; x++) { - for(uint32_t y = 0; y< y_max;y++) + for(uint32_t y = 0; y < y_max; y++) { - for(uint32_t z = 0; z< z_max;z++) + for(uint32_t z = 0; z < z_max; z++) { + if (z != z_source) + continue; // hack to cut down on targets + if(DF.isValidBlock(x,y,z)) { // read block designations and tiletype DF.ReadDesignations(x,y,z, (uint32_t *) designations); DF.ReadTileTypes(x,y,z, (uint16_t *) tiles); - // check all tiles, if type is in target list and its visible: designate for dig + // search all tiles for dig targets: + // visible, not yet marked for dig and matching tile type for (uint32_t i = 0; i < 256; i++) { if (designations[i].bits.hidden == 0 && + designations[i].bits.dig == 0 && vec_count(targets, DFHack::tileTypeTable[tiles[i]].c) > 0) { //cout << "target found at: "; //cout << x << "," << y << "," << z << "," << i << endl; - designations[i].bits.dig = DFHack::designation_default; - ++count; + + //designations[i].bits.dig = DFHack::designation_default; + //++count; + + DigTarget dt; + dt.x = x; + dt.y = y; + dt.z = z; + dt.i = i; + dt.source_distance = source_distance( + x_source, y_source, z_source, + x, y, z, i); + candidates.push_back(dt); } } - - // write the designations back - // could probably be optimized in the cases where we dont changed anything - DF.WriteDesignations(x,y,z, (uint32_t *) designations); } } } } - return count; + + // TODO the following routine doesnt check if the tile is already marked for digging + + // if we found more tiles than was requested, sort them by distance to source, + // keep the front 'num' elements and drop the rest + if (num != -1 && candidates.size() > (unsigned int)num) + { + sort(candidates.begin(), candidates.end()); + candidates.resize(num); + } + num = candidates.size(); + + // mark the tiles for actual digging + for (vector::iterator i = candidates.begin(); i != candidates.end(); ++i) + { + // TODO this could probably be made much better, theres a big chance the trees are on the same grid + DF.ReadDesignations((*i).x, (*i).y, (*i).z, (uint32_t *) designations); + designations[(*i).i].bits.dig = DFHack::designation_default; + DF.WriteDesignations((*i).x, (*i).y, (*i).z, (uint32_t *) designations); + } + + return num; } int main (int argc, const char* argv[]) @@ -96,8 +170,17 @@ int main (int argc, const char* argv[]) return 1; } DF.InitMap(); + + // TODO hack until we have a proper cli to specify origin + int x_source = 134, y_source = 134, z_source = 16; // my wagon starts here; cut trees close to wagon + //DF.InitViewAndCursor(); + //if (!DF.getViewCoords(x_source, y_source, z_source)) + //{ + // cerr << "Enable cursor" << endl; + // return 1; + //} - int count = dig(DF, targets); // <-- important part + int count = dig(DF, targets, 10, x_source, y_source, z_source); // <-- important part cout << count << " targets designated" << endl; DF.Detach(); From 4e8399a65590143423f1d2dd5ff4b713e789783d Mon Sep 17 00:00:00 2001 From: mizipzor Date: Thu, 18 Feb 2010 03:08:34 +0800 Subject: [PATCH 02/17] more digger testing --- examples/digger.cpp | 119 +++++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 47 deletions(-) diff --git a/examples/digger.cpp b/examples/digger.cpp index 958b7f089..a29662c28 100644 --- a/examples/digger.cpp +++ b/examples/digger.cpp @@ -33,31 +33,34 @@ int vec_count(vector& vec, uint16_t t) return count; } -// manhattan distance -int source_distance(int sx, int sy, int sz, - int x, int y, int z, int i) +//// manhattan distance +//int source_distance(int sx, int sy, int sz, +// int x, int y, int z, int i) +//{ +// // TODO changing x and y seems to be optimized away (?) +// cout << x << " " << i << " " << i%16 << " " << x+(i%16) << endl; +// +// // handle the fact that x,y,z refers to a 16x16 grid +// //x += i%16; +// //y += i/16; +// int dx = i%16; +// int dy = i/16; +// //x *= 16; +// //y *= 16; +// //x += dx; +// //y += dy; +// return abs(sx-(x+(i%16)))+abs(sy-(y+(i/16)))+abs(sz-z); +//} + +int manhattan_distance(int x, int y, int z, int xx, int yy, int zz) { - // TODO changing x and y seems to be optimized away (?) - cout << x << " " << i << " " << i%16 << " " << x+(i%16) << endl; - - // handle the fact that x,y,z refers to a 16x16 grid - //x += i%16; - //y += i/16; - int dx = i%16; - int dy = i/16; - //x *= 16; - //y *= 16; - //x += dx; - //y += dy; - return abs(sx-(x+(i%16)))+abs(sy-(y+(i/16)))+abs(sz-z); + return abs(x-xx)+abs(y-yy)+abs(z-zz); } struct DigTarget { int source_distance; // the distance to the source coords, used for sorting - int x, y, z; // call read designations with these and you have the tile at i - int i; // 0 <= i <= 255 - + int x, y, z; bool operator<(const DigTarget& o) { return source_distance < o.source_distance; } }; @@ -72,13 +75,16 @@ int dig(DFHack::API& DF, return 0; // max limit of 0, nothing to do uint32_t x_max,y_max,z_max; - DFHack::t_designation designations[256]; - uint16_t tiles[256]; + DFHack::t_designation designations[16][16]; + uint16_t tiles[16][16]; //uint32_t count = 0; DF.getSize(x_max,y_max,z_max); // every tile found, will later be sorted by distance to source vector candidates; + + cout << "============================" << endl; + cout << "source is " << x_source << " " << y_source << " " << z_source << endl; // walk the map for(uint32_t x = 0; x < x_max; x++) @@ -98,29 +104,35 @@ int dig(DFHack::API& DF, // search all tiles for dig targets: // visible, not yet marked for dig and matching tile type - for (uint32_t i = 0; i < 256; i++) - { - if (designations[i].bits.hidden == 0 && - designations[i].bits.dig == 0 && - vec_count(targets, DFHack::tileTypeTable[tiles[i]].c) > 0) - { - //cout << "target found at: "; - //cout << x << "," << y << "," << z << "," << i << endl; - - //designations[i].bits.dig = DFHack::designation_default; - //++count; - - DigTarget dt; - dt.x = x; - dt.y = y; - dt.z = z; - dt.i = i; - dt.source_distance = source_distance( - x_source, y_source, z_source, - x, y, z, i); - candidates.push_back(dt); - } - } + for(uint32_t lx = 0; lx < 16; lx++) + { + for(uint32_t ly = 0; ly < 16; ly++) + { + if (designations[lx][ly].bits.hidden == 0 && + designations[lx][ly].bits.dig == 0 && + vec_count(targets, DFHack::tileTypeTable[tiles[lx][ly]].c) > 0) + { + //cout << "target found at: "; + //cout << x << "," << y << "," << z << "," << i << endl; + + //designations[i].bits.dig = DFHack::designation_default; + //++count; + + DigTarget dt; + dt.x = x+lx; + dt.y = y+ly; + dt.z = z; + dt.source_distance = manhattan_distance( + x_source, y_source, z_source, + //x, y, z, i); + x+lx, y+ly, z); + candidates.push_back(dt); + + cout << "target found at " << x+lx << " " << y+ly << " " << z; + cout << ", " << dt.source_distance << " tiles to source" << endl; + } + } // local y + } // local x } } } @@ -137,13 +149,26 @@ int dig(DFHack::API& DF, } num = candidates.size(); + cout << "============================" << endl; + cout << "source is " << x_source << " " << y_source << " " << z_source << endl; + // mark the tiles for actual digging for (vector::iterator i = candidates.begin(); i != candidates.end(); ++i) { + int world_x = (*i).x/16; + int world_y = (*i).y/16; + int world_z = (*i).z; + + int local_x = (*i).x-world_x; + int local_y = (*i).y-world_y; + + cout << "designating at " << world_x+local_x << " " << world_y+local_y << " " << (*i).z; + cout << ", " << (*i).source_distance << " tiles to source" << endl; + // TODO this could probably be made much better, theres a big chance the trees are on the same grid - DF.ReadDesignations((*i).x, (*i).y, (*i).z, (uint32_t *) designations); - designations[(*i).i].bits.dig = DFHack::designation_default; - DF.WriteDesignations((*i).x, (*i).y, (*i).z, (uint32_t *) designations); + DF.ReadDesignations(world_x, world_y, world_z, (uint32_t *) designations); + designations[local_x][local_y].bits.dig = DFHack::designation_default; + DF.WriteDesignations(world_x, world_y, world_z, (uint32_t *) designations); } return num; From fefbc6e12c3fe436d53a2a3213e67c5c2e205891 Mon Sep 17 00:00:00 2001 From: mizipzor Date: Thu, 18 Feb 2010 03:28:41 +0800 Subject: [PATCH 03/17] fixed some coordinate calculation bugs --- examples/digger.cpp | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/examples/digger.cpp b/examples/digger.cpp index a29662c28..47304c908 100644 --- a/examples/digger.cpp +++ b/examples/digger.cpp @@ -85,6 +85,9 @@ int dig(DFHack::API& DF, cout << "============================" << endl; cout << "source is " << x_source << " " << y_source << " " << z_source << endl; + + int debugmaxx = 0; + int debugmaxy = 0; // walk the map for(uint32_t x = 0; x < x_max; x++) @@ -118,18 +121,26 @@ int dig(DFHack::API& DF, //designations[i].bits.dig = DFHack::designation_default; //++count; + int world_x = (x*16)+lx; + int world_y = (y*16)+ly; + DigTarget dt; - dt.x = x+lx; - dt.y = y+ly; + dt.x = world_x; + dt.y = world_y; dt.z = z; dt.source_distance = manhattan_distance( x_source, y_source, z_source, //x, y, z, i); - x+lx, y+ly, z); + world_x, world_y, z); candidates.push_back(dt); - cout << "target found at " << x+lx << " " << y+ly << " " << z; + cout << "target found at " << world_x << " " << world_y << " " << z; cout << ", " << dt.source_distance << " tiles to source" << endl; + + if (world_x > debugmaxx) + debugmaxx = world_x; + if (world_y > debugmaxy) + debugmaxy = world_y; } } // local y } // local x @@ -155,22 +166,24 @@ int dig(DFHack::API& DF, // mark the tiles for actual digging for (vector::iterator i = candidates.begin(); i != candidates.end(); ++i) { - int world_x = (*i).x/16; - int world_y = (*i).y/16; - int world_z = (*i).z; + int grid_x = (*i).x/16; + int grid_y = (*i).y/16; + int z = (*i).z; - int local_x = (*i).x-world_x; - int local_y = (*i).y-world_y; + int local_x = (*i).x-grid_x; + int local_y = (*i).y-grid_y; - cout << "designating at " << world_x+local_x << " " << world_y+local_y << " " << (*i).z; + cout << "designating at " << grid_x+local_x << " " << grid_y+local_y << " " << (*i).z; cout << ", " << (*i).source_distance << " tiles to source" << endl; // TODO this could probably be made much better, theres a big chance the trees are on the same grid - DF.ReadDesignations(world_x, world_y, world_z, (uint32_t *) designations); + DF.ReadDesignations(grid_x, grid_y, z, (uint32_t *) designations); designations[local_x][local_y].bits.dig = DFHack::designation_default; - DF.WriteDesignations(world_x, world_y, world_z, (uint32_t *) designations); + DF.WriteDesignations(grid_x, grid_y, z, (uint32_t *) designations); } + cout << debugmaxx << " " << debugmaxy << endl; + return num; } From c106222d9e9f72ae544bf7e701bb0a33ef4c8ba0 Mon Sep 17 00:00:00 2001 From: mizipzor Date: Thu, 18 Feb 2010 03:38:15 +0800 Subject: [PATCH 04/17] more coord calc fixes --- examples/digger.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/digger.cpp b/examples/digger.cpp index 47304c908..e08d99fec 100644 --- a/examples/digger.cpp +++ b/examples/digger.cpp @@ -61,7 +61,7 @@ struct DigTarget { int source_distance; // the distance to the source coords, used for sorting int x, y, z; - bool operator<(const DigTarget& o) { return source_distance < o.source_distance; } + bool operator<(const DigTarget& o) const { return source_distance < o.source_distance; } }; int dig(DFHack::API& DF, @@ -170,8 +170,8 @@ int dig(DFHack::API& DF, int grid_y = (*i).y/16; int z = (*i).z; - int local_x = (*i).x-grid_x; - int local_y = (*i).y-grid_y; + int local_x = (*i).x%grid_x; + int local_y = (*i).y%grid_y; cout << "designating at " << grid_x+local_x << " " << grid_y+local_y << " " << (*i).z; cout << ", " << (*i).source_distance << " tiles to source" << endl; From ce70eb057348a1ddf0788468b1784ab9cab4b591 Mon Sep 17 00:00:00 2001 From: mizipzor Date: Thu, 18 Feb 2010 04:43:24 +0800 Subject: [PATCH 05/17] more OO added some test cases to make sure the math works --- examples/digger.cpp | 180 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 145 insertions(+), 35 deletions(-) diff --git a/examples/digger.cpp b/examples/digger.cpp index e08d99fec..4064804d2 100644 --- a/examples/digger.cpp +++ b/examples/digger.cpp @@ -16,6 +16,7 @@ #include #include #include +#include using namespace std; #include @@ -57,11 +58,75 @@ int manhattan_distance(int x, int y, int z, int xx, int yy, int zz) return abs(x-xx)+abs(y-yy)+abs(z-zz); } -struct DigTarget +class DigTarget { +public: + DigTarget() : + source_distance(0), + grid_x(0), grid_y(0), + local_x(0), local_y(0), + real_x(0), real_y(0), z(0), + valid(false) + { + } + + DigTarget( + int realx, int realy, int _z, + int sourcex, int sourcey, int sourcez) : + //grid_x(realx/16), grid_y(realy/16), + //local_x(realx%16), local_y(realy%16), + real_x(realx), real_y(realy), z(_z), + valid(true) + { + grid_x = realx/16; + grid_y = realy/16; + + local_x = realx%16; + local_y = realy%16; + + source_distance = manhattan_distance( + real_x, real_y, z, + sourcex, sourcey, sourcez); + } + + DigTarget( + int gridx, int gridy, int _z, + int localx, int localy, + int sourcex, int sourcey, int sourcez) : + //source_distance(manhattan_distance( + // realx, realy, realz, + // sourcex, sourcey, sourcez)), + grid_x(gridx), grid_y(gridy), + local_x(localx), local_y(localy), + z(_z), + //real_x(realx), real_y(realy), real_z(realz), + valid(true) + { + real_x = (grid_x*16)+local_x; + real_y = (grid_y*16)+local_y; + + source_distance = manhattan_distance( + real_x, real_y, z, + sourcex, sourcey, sourcez); + } + int source_distance; // the distance to the source coords, used for sorting - int x, y, z; + //int source_distance() const { return _source_distance; } + + int grid_x, grid_y; + int local_x, local_y; + int real_x, real_y; + int z; + //int index; + + const bool valid; + bool operator<(const DigTarget& o) const { return source_distance < o.source_distance; } + void operator=(const DigTarget& o) const { assert(false); } // dont use + +//private: +// int source_x, source_y, source_z; +// int _source_distance; }; int dig(DFHack::API& DF, @@ -86,8 +151,8 @@ int dig(DFHack::API& DF, cout << "============================" << endl; cout << "source is " << x_source << " " << y_source << " " << z_source << endl; - int debugmaxx = 0; - int debugmaxy = 0; + //int debugmaxx = 0; + //int debugmaxy = 0; // walk the map for(uint32_t x = 0; x < x_max; x++) @@ -121,26 +186,21 @@ int dig(DFHack::API& DF, //designations[i].bits.dig = DFHack::designation_default; //++count; - int world_x = (x*16)+lx; - int world_y = (y*16)+ly; - - DigTarget dt; - dt.x = world_x; - dt.y = world_y; - dt.z = z; - dt.source_distance = manhattan_distance( - x_source, y_source, z_source, - //x, y, z, i); - world_x, world_y, z); - candidates.push_back(dt); - - cout << "target found at " << world_x << " " << world_y << " " << z; - cout << ", " << dt.source_distance << " tiles to source" << endl; - - if (world_x > debugmaxx) - debugmaxx = world_x; - if (world_y > debugmaxy) - debugmaxy = world_y; + //int realx = (x*16)+lx; + //int realy = (y*16)+ly; + + candidates.push_back(DigTarget( + x, y, z, + lx, ly, + x_source, y_source, z_source)); + + //cout << "target found at " << world_x << " " << world_y << " " << z; + //cout << ", " << dt->source_distance << " tiles to source" << endl; + + //if (world_x > debugmaxx) + // debugmaxx = world_x; + //if (world_y > debugmaxy) + // debugmaxy = world_y; } } // local y } // local x @@ -164,31 +224,81 @@ int dig(DFHack::API& DF, cout << "source is " << x_source << " " << y_source << " " << z_source << endl; // mark the tiles for actual digging - for (vector::iterator i = candidates.begin(); i != candidates.end(); ++i) + for (vector::const_iterator i = candidates.begin(); i != candidates.end(); ++i) { - int grid_x = (*i).x/16; - int grid_y = (*i).y/16; - int z = (*i).z; + //int grid_x = (*i).x/16; + //int grid_y = (*i).y/16; + //int z = (*i).z; - int local_x = (*i).x%grid_x; - int local_y = (*i).y%grid_y; + //int local_x = (*i).x%grid_x; + //int local_y = (*i).y%grid_y; - cout << "designating at " << grid_x+local_x << " " << grid_y+local_y << " " << (*i).z; + cout << "designating at " << (*i).real_x << " " << (*i).real_y << " " << (*i).z; cout << ", " << (*i).source_distance << " tiles to source" << endl; // TODO this could probably be made much better, theres a big chance the trees are on the same grid - DF.ReadDesignations(grid_x, grid_y, z, (uint32_t *) designations); - designations[local_x][local_y].bits.dig = DFHack::designation_default; - DF.WriteDesignations(grid_x, grid_y, z, (uint32_t *) designations); + // TODO move into function in DigTarget + DF.ReadDesignations((*i).grid_x, (*i).grid_y, (*i).z, (uint32_t *) designations); + designations[(*i).local_x][(*i).local_y].bits.dig = DFHack::designation_default; + DF.WriteDesignations((*i).grid_x, (*i).grid_y, (*i).z, (uint32_t *) designations); } - cout << debugmaxx << " " << debugmaxy << endl; + //cout << debugmaxx << " " << debugmaxy << endl; return num; } +void test() +{ + { + DigTarget dt; + assert(!dt.valid); + } + + { + DigTarget dt( + 20, 35, 16, + 10, 12, 14); + + assert(dt.grid_x == 1); + assert(dt.grid_y == 2); + + assert(dt.local_x == 4); + assert(dt.local_y == 3); + + assert(dt.real_x == 20); + assert(dt.real_y == 35); + + assert(dt.z == 16); + assert(dt.source_distance == 35); + assert(dt.valid); + } + + { + DigTarget dt( + 2, 4, 16, + 5, 10, + 10, 12, 14); + + assert(dt.grid_x == 2); + assert(dt.grid_y == 4); + + assert(dt.local_x == 5); + assert(dt.local_y == 10); + + assert(dt.real_x == 37); + assert(dt.real_y == 74); + + assert(dt.z == 16); + assert(dt.source_distance == 91); + assert(dt.valid); + } +} + int main (int argc, const char* argv[]) { + test(); + vector targets; for (int i = 1; i < argc; ++i) { From adb1b9e881d47942d69e5bda87697d7a32fe69a8 Mon Sep 17 00:00:00 2001 From: mizipzor Date: Thu, 18 Feb 2010 04:54:01 +0800 Subject: [PATCH 06/17] changed DigTarget to struct removed valid flag in DigTarget removed assignment operator, relies on compiler to generate one (todo, write a real one) added isequal operator test for DigTarget (todo, implement operator) it seems to mark trees correct now! :D --- examples/digger.cpp | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/examples/digger.cpp b/examples/digger.cpp index 4064804d2..3b875afa6 100644 --- a/examples/digger.cpp +++ b/examples/digger.cpp @@ -58,15 +58,14 @@ int manhattan_distance(int x, int y, int z, int xx, int yy, int zz) return abs(x-xx)+abs(y-yy)+abs(z-zz); } -class DigTarget +struct DigTarget { -public: +//public: DigTarget() : source_distance(0), grid_x(0), grid_y(0), local_x(0), local_y(0), - real_x(0), real_y(0), z(0), - valid(false) + real_x(0), real_y(0), z(0) { } @@ -75,8 +74,7 @@ public: int sourcex, int sourcey, int sourcez) : //grid_x(realx/16), grid_y(realy/16), //local_x(realx%16), local_y(realy%16), - real_x(realx), real_y(realy), z(_z), - valid(true) + real_x(realx), real_y(realy), z(_z) { grid_x = realx/16; grid_y = realy/16; @@ -98,9 +96,8 @@ public: // sourcex, sourcey, sourcez)), grid_x(gridx), grid_y(gridy), local_x(localx), local_y(localy), - z(_z), - //real_x(realx), real_y(realy), real_z(realz), - valid(true) + z(_z) + //real_x(realx), real_y(realy), real_z(realz) { real_x = (grid_x*16)+local_x; real_y = (grid_y*16)+local_y; @@ -119,10 +116,9 @@ public: int z; //int index; - const bool valid; + //const bool valid; bool operator<(const DigTarget& o) const { return source_distance < o.source_distance; } - void operator=(const DigTarget& o) const { assert(false); } // dont use //private: // int source_x, source_y, source_z; @@ -252,7 +248,7 @@ void test() { { DigTarget dt; - assert(!dt.valid); + //assert(!dt.valid); } { @@ -271,7 +267,7 @@ void test() assert(dt.z == 16); assert(dt.source_distance == 35); - assert(dt.valid); + //assert(dt.valid); } { @@ -291,8 +287,25 @@ void test() assert(dt.z == 16); assert(dt.source_distance == 91); - assert(dt.valid); + //assert(dt.valid); } + + //{ // sorting + // DigTarget a( + // 20, 35, 16, + // 10, 12, 14); + + // DigTarget b( + // 2, 4, 16, + // 5, 10, + // 10, 12, 14); + + // vector v; + // v.push_back(b); + // v.push_back(a); + // sort(v.begin(), v.end()); + // assert(*(v.begin()) == a); + //} } int main (int argc, const char* argv[]) From 1a03986cf70053dcba71ac98490295e791ea3239 Mon Sep 17 00:00:00 2001 From: mizipzor Date: Thu, 18 Feb 2010 05:10:11 +0800 Subject: [PATCH 07/17] added some windows ignores --- build/.gitignore | 1 + output/.gitignore | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 build/.gitignore create mode 100644 output/.gitignore diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 000000000..474fe987c --- /dev/null +++ b/build/.gitignore @@ -0,0 +1 @@ +build-real \ No newline at end of file diff --git a/output/.gitignore b/output/.gitignore new file mode 100644 index 000000000..45291fd1d --- /dev/null +++ b/output/.gitignore @@ -0,0 +1,3 @@ +Debug +Release +RelWithDebInfo \ No newline at end of file From 502af1e096bf633a2115fe0c1ac72afec59bc351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 18 Feb 2010 09:10:39 +0800 Subject: [PATCH 08/17] Veinlook now goes to map edges API change: isValidBlock now checks for map boundaries API change: added getBlockPtr. It returns a DF pointer to a block. --- examples/veinlook.cpp | 25 +++++++++++++++---------- library/DFHackAPI.cpp | 9 +++++++++ library/DFHackAPI.h | 4 ++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/examples/veinlook.cpp b/examples/veinlook.cpp index a77f284c1..87832944c 100644 --- a/examples/veinlook.cpp +++ b/examples/veinlook.cpp @@ -272,11 +272,12 @@ main(int argc, char *argv[]) finish(0); } + // FIXME: could fail on small forts int cursorX = x_max/2 - 1; int cursorY = y_max/2 - 1; int cursorZ = z_max/2 - 1; - // FIXME: could fail on small forts + int vein = 0; // walk the map! @@ -318,13 +319,15 @@ main(int argc, char *argv[]) cursorY = max(cursorY, 0); cursorZ = max(cursorZ, 0); - cursorX = min(cursorX, x_max - 3); - cursorY = min(cursorY, y_max - 3); - cursorZ = min(cursorZ, z_max - 3); + cursorX = min(cursorX, x_max - 1); + cursorY = min(cursorY, y_max - 1); + cursorZ = min(cursorZ, z_max - 1); DF.Suspend(); - for(int i = 0; i < 3; i++) - for(int j = 0; j < 3; j++) + for(int i = -1; i <= 1; i++) + { + for(int j = -1; j <= 1; j++) + { if(DF.isValidBlock(cursorX+i,cursorY+j,cursorZ)) { // read data @@ -338,22 +341,24 @@ main(int argc, char *argv[]) color = pickColor(tiletypes[x][y]); if(designations[x][y].bits.hidden) { - puttile(x+i*16,y+j*16,tiletypes[x][y], color); + puttile(x+(i+1)*16,y+(j+1)*16,tiletypes[x][y], color); } else { attron(A_STANDOUT); - puttile(x+i*16,y+j*16,tiletypes[x][y], color); + puttile(x+(i+1)*16,y+(j+1)*16,tiletypes[x][y], color); attroff(A_STANDOUT); } } } - if(i == 1 && j == 1) + if(i == 0 && j == 0) { veinVector.clear(); DF.ReadVeins(cursorX+i,cursorY+j,cursorZ,veinVector); } } + } + } gotoxy(0,48); cprintf("arrow keys, PGUP, PGDN = navigate"); gotoxy(0,49); @@ -361,7 +366,7 @@ main(int argc, char *argv[]) gotoxy(0,50); if(vein == veinVector.size()) vein = veinVector.size() - 1; if(vein < -1) vein = -1; - cprintf("X %d/%d, Y %d/%d, Z %d/%d. Vein %d of %d",cursorX + 1,x_max,cursorY + 1,y_max,cursorZ + 1,z_max,vein+1,veinVector.size()); + cprintf("X %d/%d, Y %d/%d, Z %d/%d. Vein %d of %d",cursorX+1,x_max,cursorY+1,y_max,cursorZ,z_max,vein+1,veinVector.size()); if(!veinVector.empty()) { if(vein != -1 && vein < veinVector.size()) diff --git a/library/DFHackAPI.cpp b/library/DFHackAPI.cpp index 602f90e60..3594773dd 100644 --- a/library/DFHackAPI.cpp +++ b/library/DFHackAPI.cpp @@ -221,9 +221,18 @@ bool API::DestroyMap() bool API::isValidBlock (uint32_t x, uint32_t y, uint32_t z) { + if (x < 0 || x >= d->x_block_count || y < 0 || y >= d->y_block_count || z < 0 || z >= d->z_block_count) + return false; return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z] != 0; } +uint32_t API::getBlockPtr (uint32_t x, uint32_t y, uint32_t z) +{ + if (x < 0 || x >= d->x_block_count || y < 0 || y >= d->y_block_count || z < 0 || z >= d->z_block_count) + return 0; + return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; +} + // 256 * sizeof(uint16_t) bool API::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, uint16_t *buffer) { diff --git a/library/DFHackAPI.h b/library/DFHackAPI.h index ce7ef8dac..7601d17d7 100644 --- a/library/DFHackAPI.h +++ b/library/DFHackAPI.h @@ -128,6 +128,10 @@ 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 + */ + uint32_t getBlockPtr (uint32_t x, uint32_t y, uint32_t z); bool ReadTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint16_t *buffer); // 256 * sizeof(uint16_t) bool WriteTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint16_t *buffer); // 256 * sizeof(uint16_t) From 2bd46abe81238e3f16c6af01510c1565c6c49bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 18 Feb 2010 11:03:30 +0800 Subject: [PATCH 09/17] Added some more ignore rules --- .gitignore | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..10760875f --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# linux backup files +*~ + +# compiled binaries +output/* + +# this one is important, track it +!output/Memory.xml + +# a file generated by cmake +library/config.h + +# any build folders +build*/ + +#except for the real one +!build/ + +#ignore Kdevelop stuff +.kdev4 From 448cadd5be14811c68f10f5bbb5edeaa5c88facc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 19 Feb 2010 00:58:25 +0800 Subject: [PATCH 10/17] Veinlook shows material of mineral veins --- examples/veinlook.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/veinlook.cpp b/examples/veinlook.cpp index 87832944c..5e81803c4 100644 --- a/examples/veinlook.cpp +++ b/examples/veinlook.cpp @@ -407,6 +407,8 @@ main(int argc, char *argv[]) } } } + gotoxy(0,52); + cprintf("%s",stonetypes[veinVector[vein].type].name); } gotoxy(0,51); cprintf("%s, address 0x%x",str.c_str(),veinVector[vein].address_of); From bc3c08e6c47cf2b05e07c30b068d98eece953ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 19 Feb 2010 01:06:32 +0800 Subject: [PATCH 11/17] Tabs to spaces --- examples/hotkeynotedump.cpp | 60 +++++++++---------- library/DFHackAPI.cpp | 76 ++++++++++++------------- library/DFHackAPI.h | 10 ++-- library/DFProcessEnumerator-windows.cpp | 4 +- library/DFTypes.h | 22 +++---- 5 files changed, 86 insertions(+), 86 deletions(-) diff --git a/examples/hotkeynotedump.cpp b/examples/hotkeynotedump.cpp index cda81ab34..9685e33d5 100644 --- a/examples/hotkeynotedump.cpp +++ b/examples/hotkeynotedump.cpp @@ -1,5 +1,5 @@ // Hotkey and Note Dump - +// Or Hot Keynote Dump? :P #include #include #include @@ -21,38 +21,38 @@ int main (void) return 1; } - DFHack::memory_info mem = DF.getMemoryInfo(); + DFHack::memory_info mem = DF.getMemoryInfo(); // get stone matgloss mapping - uint32_t numNotes; - if(!DF.InitReadNotes(numNotes)) - { - cerr << "Can't get notes" << endl; - return 1; - } - if(!DF.InitReadHotkeys()) - { - cerr << "Can't get hotkeys" << endl; - return 1; - } - cout << "Notes" << endl; + uint32_t numNotes; + if(!DF.InitReadNotes(numNotes)) + { + cerr << "Can't get notes" << endl; + return 1; + } + if(!DF.InitReadHotkeys()) + { + cerr << "Can't get hotkeys" << endl; + return 1; + } + cout << "Notes" << endl; for(uint32_t i = 0; i < numNotes; i++) { - DFHack::t_note temp; - DF.ReadNote(i,temp); - cout << "x: " << temp.x << "\ty: " << temp.y << "\tz: " << temp.z << - "\tsymbol: " << temp.symbol << "\tfg: " << temp.foreground << "\tbg: " << temp.background << - "\ttext: " << temp.name << endl; - } - cout << "Hotkeys" << endl; - DFHack::t_hotkey hotkeys[NUM_HOTKEYS]; - DF.ReadHotkeys(hotkeys); - for(uint32_t i =0;i< NUM_HOTKEYS;i++) - { - cout << "x: " << hotkeys[i].x << "\ty: " << hotkeys[i].y << "\tz: " << hotkeys[i].z << - "\ttext: " << hotkeys[i].name << endl; - } - DF.FinishReadNotes(); - DF.Detach(); + DFHack::t_note temp; + DF.ReadNote(i,temp); + cout << "x: " << temp.x << "\ty: " << temp.y << "\tz: " << temp.z << + "\tsymbol: " << temp.symbol << "\tfg: " << temp.foreground << "\tbg: " << temp.background << + "\ttext: " << temp.name << endl; + } + cout << "Hotkeys" << endl; + DFHack::t_hotkey hotkeys[NUM_HOTKEYS]; + DF.ReadHotkeys(hotkeys); + for(uint32_t i =0;i< NUM_HOTKEYS;i++) + { + cout << "x: " << hotkeys[i].x << "\ty: " << hotkeys[i].y << "\tz: " << hotkeys[i].z << + "\ttext: " << hotkeys[i].name << endl; + } + DF.FinishReadNotes(); + DF.Detach(); #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); diff --git a/library/DFHackAPI.cpp b/library/DFHackAPI.cpp index 3594773dd..18334c2db 100644 --- a/library/DFHackAPI.cpp +++ b/library/DFHackAPI.cpp @@ -83,14 +83,14 @@ public: uint32_t item_material_offset; - uint32_t note_foreground_offset; - uint32_t note_background_offset; - uint32_t note_name_offset; - uint32_t note_xyz_offset; - uint32_t hotkey_start; - uint32_t hotkey_mode_offset; - uint32_t hotkey_xyz_offset; - uint32_t hotkey_size; + uint32_t note_foreground_offset; + uint32_t note_background_offset; + uint32_t note_name_offset; + uint32_t note_xyz_offset; + uint32_t hotkey_start; + uint32_t hotkey_mode_offset; + uint32_t hotkey_xyz_offset; + uint32_t hotkey_size; uint32_t dwarf_lang_table_offset; @@ -107,8 +107,8 @@ public: bool cursorWindowInited; bool viewSizeInited; bool itemsInited; - bool notesInited; - bool hotkeyInited; + bool notesInited; + bool hotkeyInited; bool nameTablesInited; @@ -118,7 +118,7 @@ public: DfVector *p_bld; DfVector *p_veg; DfVector *p_itm; - DfVector *p_notes; + DfVector *p_notes; }; API::API (const string path_to_xml) @@ -134,8 +134,8 @@ API::API (const string path_to_xml) d->cursorWindowInited = false; d->viewSizeInited = false; d->itemsInited = false; - d->notesInited = false; - d->hotkeyInited = false; + d->notesInited = false; + d->hotkeyInited = false; d->pm = NULL; } @@ -860,7 +860,7 @@ bool API::InitReadCreatures( uint32_t &numcreatures ) && d->creature_labors_offset && d->creature_happiness_offset && d->creature_traits_offset - // && d->creature_likes_offset + // && d->creature_likes_offset ) { d->p_cre = new DfVector (d->p->readVector (creatures, 4)); @@ -881,9 +881,9 @@ bool API::InitReadNotes( uint32_t &numnotes ) memory_info * minfo = d->offset_descriptor; int notes = d->offset_descriptor->getAddress ("notes"); d->note_foreground_offset = minfo->getOffset ("note_foreground"); - d->note_background_offset = minfo->getOffset ("note_background"); - d->note_name_offset = minfo->getOffset ("note_name"); - d->note_xyz_offset = minfo->getOffset ("note_xyz"); + d->note_background_offset = minfo->getOffset ("note_background"); + d->note_name_offset = minfo->getOffset ("note_name"); + d->note_xyz_offset = minfo->getOffset ("note_xyz"); if (notes && d->note_foreground_offset @@ -910,25 +910,25 @@ bool API::ReadNote (const int32_t &index, t_note & note) assert (d->notesInited); // read pointer from vector at position uint32_t temp = * (uint32_t *) d->p_notes->at (index); - note.symbol = g_pProcess->readByte(temp); - note.foreground = g_pProcess->readWord(temp + d->note_foreground_offset); - note.background = g_pProcess->readWord(temp + d->note_background_offset); - d->p->readSTLString (temp + d->note_name_offset, note.name, 128); - g_pProcess->read (temp + d->note_xyz_offset, 3*sizeof (uint16_t), (uint8_t *) ¬e.x); - return true; + note.symbol = g_pProcess->readByte(temp); + note.foreground = g_pProcess->readWord(temp + d->note_foreground_offset); + note.background = g_pProcess->readWord(temp + d->note_background_offset); + d->p->readSTLString (temp + d->note_name_offset, note.name, 128); + g_pProcess->read (temp + d->note_xyz_offset, 3*sizeof (uint16_t), (uint8_t *) ¬e.x); + return true; } bool API::InitReadHotkeys( ) { memory_info * minfo = d->offset_descriptor; - d->hotkey_start = minfo->getAddress("hotkey_start"); + d->hotkey_start = minfo->getAddress("hotkey_start"); d->hotkey_mode_offset = minfo->getOffset ("hotkey_mode"); - d->hotkey_xyz_offset = minfo->getOffset("hotkey_xyz"); - d->hotkey_size = minfo->getHexValue("hotkey_size"); - + d->hotkey_xyz_offset = minfo->getOffset("hotkey_xyz"); + d->hotkey_size = minfo->getHexValue("hotkey_size"); + if (d->hotkey_start && d->hotkey_mode_offset && d->hotkey_size) { - d->hotkeyInited = true; - return true; + d->hotkeyInited = true; + return true; } else { @@ -939,15 +939,15 @@ bool API::InitReadHotkeys( ) bool API::ReadHotkeys(t_hotkey hotkeys[]) { assert (d->hotkeyInited); - uint32_t currHotkey = d->hotkey_start; - for(uint32_t i = 0 ; i < NUM_HOTKEYS ;i++) - { - d->p->readSTLString(currHotkey,hotkeys[i].name,10); - hotkeys[i].mode = g_pProcess->readWord(currHotkey+d->hotkey_mode_offset); - g_pProcess->read (currHotkey + d->hotkey_xyz_offset, 3*sizeof (int32_t), (uint8_t *) &hotkeys[i].x); - currHotkey+=d->hotkey_size; - } - return true; + uint32_t currHotkey = d->hotkey_start; + for(uint32_t i = 0 ; i < NUM_HOTKEYS ;i++) + { + d->p->readSTLString(currHotkey,hotkeys[i].name,10); + hotkeys[i].mode = g_pProcess->readWord(currHotkey+d->hotkey_mode_offset); + g_pProcess->read (currHotkey + d->hotkey_xyz_offset, 3*sizeof (int32_t), (uint8_t *) &hotkeys[i].x); + currHotkey+=d->hotkey_size; + } + return true; } // returns index of creature actually read or -1 if no creature can be found int32_t API::ReadCreatureInBox (int32_t index, t_creature & furball, diff --git a/library/DFHackAPI.h b/library/DFHackAPI.h index 7601d17d7..f41647261 100644 --- a/library/DFHackAPI.h +++ b/library/DFHackAPI.h @@ -176,12 +176,12 @@ namespace DFHack bool InitViewAndCursor(); - bool InitReadNotes( uint32_t & numnotes ); - bool ReadNote(const int32_t &index, t_note & note); - void FinishReadNotes(); + bool InitReadNotes( uint32_t & numnotes ); + bool ReadNote(const int32_t &index, t_note & note); + void FinishReadNotes(); - bool InitReadHotkeys( ); - bool ReadHotkeys(t_hotkey hotkeys[]); + bool InitReadHotkeys( ); + bool ReadHotkeys(t_hotkey hotkeys[]); bool getViewCoords (int32_t &x, int32_t &y, int32_t &z); bool setViewCoords (const int32_t &x, const int32_t &y, const int32_t &z); diff --git a/library/DFProcessEnumerator-windows.cpp b/library/DFProcessEnumerator-windows.cpp index 19491c279..f08aec558 100644 --- a/library/DFProcessEnumerator-windows.cpp +++ b/library/DFProcessEnumerator-windows.cpp @@ -73,7 +73,7 @@ bool ProcessEnumerator::findProcessess() if(p->isIdentified()) { d->processes.push_back(p); - return true; + return true; } else { @@ -103,7 +103,7 @@ bool ProcessEnumerator::findProcessess() else { //FIXME delete q; - q = 0; + q = 0; } } if(d->processes.size()) diff --git a/library/DFTypes.h b/library/DFTypes.h index 717c82180..50e36d898 100644 --- a/library/DFTypes.h +++ b/library/DFTypes.h @@ -756,22 +756,22 @@ struct t_viewscreen struct t_note { char symbol; - uint16_t foreground; - uint16_t background; - char name[128]; - uint16_t x; - uint16_t y; - uint16_t z; + uint16_t foreground; + uint16_t background; + char name[128]; + uint16_t x; + uint16_t y; + uint16_t z; }; #define NUM_HOTKEYS 16 struct t_hotkey { - char name[10]; - int16_t mode; - int32_t x; - int32_t y; - int32_t z; + char name[10]; + int16_t mode; + int32_t x; + int32_t y; + int32_t z; }; }// namespace DFHack From d7c627033bd78e1761e80d686b85f447b672d099 Mon Sep 17 00:00:00 2001 From: mizipzor Date: Fri, 19 Feb 2010 01:09:05 +0800 Subject: [PATCH 12/17] moved digger.cpp to tools/ --- {examples => tools}/digger.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {examples => tools}/digger.cpp (100%) diff --git a/examples/digger.cpp b/tools/digger.cpp similarity index 100% rename from examples/digger.cpp rename to tools/digger.cpp From a9863ecfec31484664adc37df62c422c142087f0 Mon Sep 17 00:00:00 2001 From: mizipzor Date: Fri, 19 Feb 2010 01:23:09 +0800 Subject: [PATCH 13/17] added gopt --- library/gopt/gopt.c | 265 ++++++++++++++++++++++++++++++++++++++++++++ library/gopt/gopt.h | 60 ++++++++++ 2 files changed, 325 insertions(+) create mode 100644 library/gopt/gopt.c create mode 100644 library/gopt/gopt.h diff --git a/library/gopt/gopt.c b/library/gopt/gopt.c new file mode 100644 index 000000000..48f278867 --- /dev/null +++ b/library/gopt/gopt.c @@ -0,0 +1,265 @@ +/* gopt.c version 8.1: tom.viza@gmail.com PUBLIC DOMAIN 2003-8 */ +/* +I, Tom Vajzovic, am the author of this software and its documentation and +permanently abandon all copyright and other intellectual property rights in +them, including the right to be identified as the author. + +I am fairly certain that this software does what the documentation says it +does, but I cannot guarantee that it does, or that it does what you think it +should, and I cannot guarantee that it will not have undesirable side effects. + +You are free to use, modify and distribute this software as you please, but +you do so at your own risk. If you remove or hide this warning then you are +responsible for any problems encountered by people that you make the software +available to. + +Before modifying or distributing this software I ask that you would please +read http://www.purposeful.co.uk/tfl/ +*/ + +#include +#include +#include +#include "gopt.h" + +#ifdef USE_SYSEXITS +#include +#else +#define EX_OSERR EXIT_FAILURE +#define EX_USAGE EXIT_FAILURE +#endif + +struct opt_spec_s { + int key; + int flags; + const char *shorts; + const char* const *longs; +}; +typedef struct opt_spec_s opt_spec_t; + +struct opt_s { + int key; + const char *arg; +}; +typedef struct opt_s opt_t; + +void *gopt_sort( int *argc, const char **argv, const void *opt_specs ){ + void *opts; + {{{ + const char* const *arg_p= argv + 1; + size_t opt_count= 1; + for( ; *arg_p; ++arg_p ) + if( '-' == (*arg_p)[0] && (*arg_p)[1] ) + if( '-' == (*arg_p)[1] ) + if( (*arg_p)[2] ) + ++opt_count; + else + break; + else { + const opt_spec_t *opt_spec_p= opt_specs; + for( ; opt_spec_p-> key; ++opt_spec_p ) + if( strchr( opt_spec_p-> shorts, (*arg_p)[1] )){ + opt_count+= opt_spec_p-> flags & GOPT_ARG ? 1 : strlen( (*arg_p) + 1 ); + break; + } + } + opts= malloc( opt_count * sizeof(opt_t) ); + }}} + { + const char **arg_p= argv + 1; + const char **next_operand= arg_p; + opt_t *next_option= opts; + + if( ! opts ){ + perror( argv[0] ); + exit( EX_OSERR ); + } + for( ; *arg_p; ++arg_p ) + if( '-' == (*arg_p)[0] && (*arg_p)[1] ) + if( '-' == (*arg_p)[1] ) + if( (*arg_p)[2] ) + {{{ + const opt_spec_t *opt_spec_p= opt_specs; + const char* const *longs= opt_spec_p-> longs; + next_option-> key= 0; + while( *longs ){ + const char *option_cp= (*arg_p) + 2; + const char *name_cp= *longs; + while( *option_cp && *option_cp == *name_cp ){ + ++option_cp; + ++name_cp; + } + if( '=' == *option_cp || !*option_cp ){ + if( *name_cp ){ + if( next_option-> key ){ + fprintf( stderr, "%s: --%.*s: abbreviated option is ambiguous\n", argv[0], (int)( option_cp -( (*arg_p) + 2 )), (*arg_p) + 2 ); + free( opts ); + exit( EX_USAGE ); + } + next_option-> key= opt_spec_p-> key; + } + else { + next_option-> key= opt_spec_p-> key; + goto found_long; + } + } + if( !*++longs ){ + ++opt_spec_p; + if( opt_spec_p-> key ) + longs= opt_spec_p-> longs; + } + } + if( ! next_option-> key ){ + fprintf( stderr, "%s: --%.*s: unknown option\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 ); + free( opts ); + exit( EX_USAGE ); + } + for( opt_spec_p= opt_specs; opt_spec_p-> key != next_option-> key; ++opt_spec_p ); + found_long: + + if( !( opt_spec_p-> flags & GOPT_REPEAT )){ + const opt_t *opt_p= opts; + for( ; opt_p != next_option; ++opt_p ) + if( opt_p-> key == opt_spec_p-> key ){ + fprintf( stderr, "%s: --%.*s: option may not be repeated (in any long or short form)\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 ); + free( opts ); + exit( EX_USAGE ); + } + } + if( opt_spec_p-> flags & GOPT_ARG ){ + next_option-> arg= strchr( (*arg_p) + 2, '=' ) + 1; + if( (char*)0 + 1 == next_option-> arg ){ + ++arg_p; + if( !*arg_p || '-' == (*arg_p)[0] && (*arg_p)[1] ){ + fprintf( stderr, "%s: --%s: option requires an option argument\n", argv[0], (*(arg_p-1)) + 2 ); + free( opts ); + exit( EX_USAGE ); + } + next_option-> arg= *arg_p; + } + } + else { + if( strchr( (*arg_p) + 2, '=' )){ + fprintf( stderr, "%s: --%.*s: option may not take an option argument\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 ); + free( opts ); + exit( EX_USAGE ); + } + next_option-> arg= NULL; + } + ++next_option; + }}} + else { + for( ++arg_p; *arg_p; ++arg_p ) + *next_operand++= *arg_p; + break; + } + else + {{{ + const char *short_opt= (*arg_p) + 1; + for( ;*short_opt; ++short_opt ){ + const opt_spec_t *opt_spec_p= opt_specs; + + for( ; opt_spec_p-> key; ++opt_spec_p ) + if( strchr( opt_spec_p-> shorts, *short_opt )){ + if( !( opt_spec_p-> flags & GOPT_REPEAT )){ + const opt_t *opt_p= opts; + for( ; opt_p != next_option; ++opt_p ) + if( opt_p-> key == opt_spec_p-> key ){ + fprintf( stderr, "%s: -%c: option may not be repeated (in any long or short form)\n", argv[0], *short_opt ); + free( opts ); + exit( EX_USAGE ); + } + } + next_option-> key= opt_spec_p-> key; + + if( opt_spec_p-> flags & GOPT_ARG ){ + if( short_opt[1] ) + next_option-> arg= short_opt + 1; + + else { + ++arg_p; + if( !*arg_p || '-' == (*arg_p)[0] && (*arg_p)[1] ){ + fprintf( stderr, "%s: -%c: option requires an option argument\n", argv[0], *short_opt ); + free( opts ); + exit( EX_USAGE ); + } + next_option-> arg= *arg_p; + } + ++next_option; + goto break_2; + } + next_option-> arg= NULL; + ++next_option; + goto continue_2; + } + fprintf( stderr, "%s: -%c: unknown option\n", argv[0], *short_opt ); + free( opts ); + exit( EX_USAGE ); + continue_2: 0; + } + break_2: 0; + }}} + else + *next_operand++= *arg_p; + + next_option-> key= 0; + *next_operand= NULL; + *argc= next_operand - argv; + } + return opts; +} + +size_t gopt( const void *vptr_opts, int key ){ + const opt_t *opts= vptr_opts; + size_t count= 0; + for( ; opts-> key; ++opts ) + count+= opts-> key == key; + + return count; +} + +size_t gopt_arg( const void *vptr_opts, int key, const char **arg ){ + const opt_t *opts= vptr_opts; + size_t count= 0; + + for( ; opts-> key; ++opts ) + if( opts-> key == key ){ + if( ! count ) + *arg= opts-> arg; + ++count; + } + return count; +} + +const char *gopt_arg_i( const void *vptr_opts, int key, size_t i ){ + const opt_t *opts= vptr_opts; + + for( ; opts-> key; ++opts ) + if( opts-> key == key ){ + if( ! i ) + return opts-> arg; + --i; + } + return NULL; +} + +size_t gopt_args( const void *vptr_opts, int key, const char **args, size_t args_len ){ + const char **args_stop= args + args_len; + const char **args_ptr= args; + const opt_t *opts= vptr_opts; + + for( ; opts-> key; ++opts ) + if( opts-> key == key ){ + if( args_stop == args_ptr ) + return args_len + gopt( opts, key ); + + *args_ptr++= opts-> arg; + } + if( args_stop != args_ptr ) + *args_ptr= NULL; + return args_ptr - args; +} + +void gopt_free( void *vptr_opts ){ + free( vptr_opts ); +} diff --git a/library/gopt/gopt.h b/library/gopt/gopt.h new file mode 100644 index 000000000..93885a12f --- /dev/null +++ b/library/gopt/gopt.h @@ -0,0 +1,60 @@ +/* gopt.h version 8.1: tom.viza@gmail.com PUBLIC DOMAIN 2003-8 */ +/* +I, Tom Vajzovic, am the author of this software and its documentation and +permanently abandon all copyright and other intellectual property rights in +them, including the right to be identified as the author. + +I am fairly certain that this software does what the documentation says it +does, but I cannot guarantee that it does, or that it does what you think it +should, and I cannot guarantee that it will not have undesirable side effects. + +You are free to use, modify and distribute this software as you please, but +you do so at your own risk. If you remove or hide this warning then you are +responsible for any problems encountered by people that you make the software +available to. + +Before modifying or distributing this software I ask that you would please +read http://www.purposeful.co.uk/tfl/ +*/ + +#ifndef GOPT_H_INCLUDED +#define GOPT_H_INCLUDED + +#define GOPT_ONCE 0 +#define GOPT_REPEAT 1 +#define GOPT_NOARG 0 +#define GOPT_ARG 2 + +#define gopt_start(...) (const void*)( const struct { int k; int f; const char *s; const char*const*l; }[]){ __VA_ARGS__, {0}} +#define gopt_option(k,f,s,l) { k, f, s, l } +#define gopt_shorts( ... ) (const char*)(const char[]){ __VA_ARGS__, 0 } +#define gopt_longs( ... ) (const char**)(const char*[]){ __VA_ARGS__, NULL } + + +void *gopt_sort( int *argc, const char **argv, const void *opt_specs ); +/* returns a pointer for use in the following calls + * prints to stderr and call exit() on error + */ +size_t gopt( const void *opts, int key ); +/* returns the number of times the option was specified + * which will be 0 or 1 unless GOPT_REPEAT was used + */ +size_t gopt_arg( const void *opts, int key, const char **arg ); +/* returns the number of times the option was specified + * writes a pointer to the option argument from the first (or only) occurance to *arg + */ +const char *gopt_arg_i( const void *opts, int key, size_t i ); +/* returns a pointer to the ith (starting at zero) occurance + * of the option, or NULL if it was not specified that many times + */ +size_t gopt_args( const void *opts, int key, const char **args, size_t args_len ); +/* returns the number of times the option was specified + * writes pointers to the option arguments in the order of occurance to args[]. + * writes at most args_len pointers + * if the return value is less than args_len, also writes a null pointer + */ +void gopt_free( void *opts ); +/* releases memory allocated in the corresponding call to gopt_sort() + * opts can no longer be used + */ +#endif /* GOPT_H_INCLUDED */ From 5b8a33e7c86e00386dccc7b6a0546fa335b345f5 Mon Sep 17 00:00:00 2001 From: mizipzor Date: Fri, 19 Feb 2010 01:25:24 +0800 Subject: [PATCH 14/17] fixed compile errors in gopt --- library/gopt/gopt.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/library/gopt/gopt.c b/library/gopt/gopt.c index 48f278867..4deeeb5c1 100644 --- a/library/gopt/gopt.c +++ b/library/gopt/gopt.c @@ -56,7 +56,7 @@ void *gopt_sort( int *argc, const char **argv, const void *opt_specs ){ else break; else { - const opt_spec_t *opt_spec_p= opt_specs; + const opt_spec_t *opt_spec_p= (const opt_spec_t*)opt_specs; for( ; opt_spec_p-> key; ++opt_spec_p ) if( strchr( opt_spec_p-> shorts, (*arg_p)[1] )){ opt_count+= opt_spec_p-> flags & GOPT_ARG ? 1 : strlen( (*arg_p) + 1 ); @@ -68,7 +68,7 @@ void *gopt_sort( int *argc, const char **argv, const void *opt_specs ){ { const char **arg_p= argv + 1; const char **next_operand= arg_p; - opt_t *next_option= opts; + opt_t *next_option= (opt_t*)opts; if( ! opts ){ perror( argv[0] ); @@ -79,7 +79,7 @@ void *gopt_sort( int *argc, const char **argv, const void *opt_specs ){ if( '-' == (*arg_p)[1] ) if( (*arg_p)[2] ) {{{ - const opt_spec_t *opt_spec_p= opt_specs; + const opt_spec_t *opt_spec_p= (const opt_spec_t*)opt_specs; const char* const *longs= opt_spec_p-> longs; next_option-> key= 0; while( *longs ){ @@ -114,11 +114,11 @@ void *gopt_sort( int *argc, const char **argv, const void *opt_specs ){ free( opts ); exit( EX_USAGE ); } - for( opt_spec_p= opt_specs; opt_spec_p-> key != next_option-> key; ++opt_spec_p ); + for( opt_spec_p= (const opt_spec_t*)opt_specs; opt_spec_p-> key != next_option-> key; ++opt_spec_p ); found_long: if( !( opt_spec_p-> flags & GOPT_REPEAT )){ - const opt_t *opt_p= opts; + const opt_t *opt_p= (const opt_t*)opts; for( ; opt_p != next_option; ++opt_p ) if( opt_p-> key == opt_spec_p-> key ){ fprintf( stderr, "%s: --%.*s: option may not be repeated (in any long or short form)\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 ); @@ -157,12 +157,12 @@ void *gopt_sort( int *argc, const char **argv, const void *opt_specs ){ {{{ const char *short_opt= (*arg_p) + 1; for( ;*short_opt; ++short_opt ){ - const opt_spec_t *opt_spec_p= opt_specs; + const opt_spec_t *opt_spec_p= (const opt_spec_t*)opt_specs; for( ; opt_spec_p-> key; ++opt_spec_p ) if( strchr( opt_spec_p-> shorts, *short_opt )){ if( !( opt_spec_p-> flags & GOPT_REPEAT )){ - const opt_t *opt_p= opts; + const opt_t *opt_p= (const opt_t*)opts; for( ; opt_p != next_option; ++opt_p ) if( opt_p-> key == opt_spec_p-> key ){ fprintf( stderr, "%s: -%c: option may not be repeated (in any long or short form)\n", argv[0], *short_opt ); @@ -210,7 +210,7 @@ void *gopt_sort( int *argc, const char **argv, const void *opt_specs ){ } size_t gopt( const void *vptr_opts, int key ){ - const opt_t *opts= vptr_opts; + const opt_t *opts= (const opt_t*)vptr_opts; size_t count= 0; for( ; opts-> key; ++opts ) count+= opts-> key == key; @@ -219,7 +219,7 @@ size_t gopt( const void *vptr_opts, int key ){ } size_t gopt_arg( const void *vptr_opts, int key, const char **arg ){ - const opt_t *opts= vptr_opts; + const opt_t *opts= (const opt_t*)vptr_opts; size_t count= 0; for( ; opts-> key; ++opts ) @@ -232,7 +232,7 @@ size_t gopt_arg( const void *vptr_opts, int key, const char **arg ){ } const char *gopt_arg_i( const void *vptr_opts, int key, size_t i ){ - const opt_t *opts= vptr_opts; + const opt_t *opts= (const opt_t*)vptr_opts; for( ; opts-> key; ++opts ) if( opts-> key == key ){ @@ -246,7 +246,7 @@ const char *gopt_arg_i( const void *vptr_opts, int key, size_t i ){ size_t gopt_args( const void *vptr_opts, int key, const char **args, size_t args_len ){ const char **args_stop= args + args_len; const char **args_ptr= args; - const opt_t *opts= vptr_opts; + const opt_t *opts= (const opt_t*)vptr_opts; for( ; opts-> key; ++opts ) if( opts-> key == key ){ From 4d9ecb31b718bc9ff82edbe4a0877c655645568a Mon Sep 17 00:00:00 2001 From: mizipzor Date: Fri, 19 Feb 2010 01:31:18 +0800 Subject: [PATCH 15/17] added gopt to CMakeLists.txt --- library/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 12de11fbd..4eae87b63 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -19,6 +19,8 @@ md5/md5wrapper.h tinyxml/tinystr.h tinyxml/tinyxml.h +gopt/gopt.h + ../shmserver/shms.h ) @@ -33,6 +35,7 @@ tinyxml/tinystr.cpp tinyxml/tinyxml.cpp tinyxml/tinyxmlerror.cpp tinyxml/tinyxmlparser.cpp +gopt/gopt.c ) SET(PROJECT_HDRS_LINUX From 423bad28208634b176787585a572bc7e27b4de5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 19 Feb 2010 03:16:05 +0800 Subject: [PATCH 16/17] Missed one glitch in the merge --- examples/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9aa1cec5f..c16c1104f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -63,7 +63,6 @@ dfattachtest dfbuildingsdump dfcreaturedump dfitemdump -dfdigger dfexpbench dfmaterialtest dfposition From 20a74354c513a56b410e018436036ff5c2b1543f Mon Sep 17 00:00:00 2001 From: belal Date: Thu, 18 Feb 2010 20:13:53 -0500 Subject: [PATCH 17/17] findnameindexes - finds the indexes for a compound name, not very smart, but it works! Signed-off-by: belal --- examples/CMakeLists.txt | 5 ---- tools/CMakeLists.txt | 9 +++++++ tools/findnameindexes.cpp | 49 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 tools/findnameindexes.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c16c1104f..058d5014c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -37,11 +37,6 @@ TARGET_LINK_LIBRARIES(dfsuspend dfhack) ADD_EXECUTABLE(dfitemdump dfitemdump.cpp) TARGET_LINK_LIBRARIES(dfitemdump dfhack) -# digger - designate for digging by tile class -# Author: mizipzor -ADD_EXECUTABLE(dfdigger digger.cpp) -TARGET_LINK_LIBRARIES(dfdigger dfhack) - # hotkeynotedump - dumps the hotkeys and notes for the loaded map # Author: belal ADD_EXECUTABLE(dfhotkeynotedump hotkeynotedump.cpp) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 6a6fa9f95..ab93a9660 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -26,10 +26,19 @@ TARGET_LINK_LIBRARIES(dfincremental dfhack) ADD_EXECUTABLE(dfbauxite dfbauxite.cpp) TARGET_LINK_LIBRARIES(dfbauxite dfhack) +# digger - designate for digging by tile class +# Author: mizipzor +ADD_EXECUTABLE(dfdigger digger.cpp) +TARGET_LINK_LIBRARIES(dfdigger dfhack) + + # itemdesignator - change some item designations (dump, forbid, on-fire) for all items of a given type and material ADD_EXECUTABLE(dfitemdesignator itemdesignator.cpp) TARGET_LINK_LIBRARIES(dfitemdesignator dfhack) +ADD_EXECUTABLE(dffindnameindexes findnameindexes.cpp) +TARGET_LINK_LIBRARIES(dffindnameindexes dfhack) + IF(UNIX) install(TARGETS dfreveal diff --git a/tools/findnameindexes.cpp b/tools/findnameindexes.cpp new file mode 100644 index 000000000..7765e5656 --- /dev/null +++ b/tools/findnameindexes.cpp @@ -0,0 +1,49 @@ +// Map cleaner. Removes all the snow, mud spills, blood and vomit from map tiles. + +#include +#include +#include +#include +using namespace std; + +#include +#include + +int main (void) +{ + DFHack::API DF ("Memory.xml"); + if(!DF.Attach()) + { + cerr << "DF not found" << endl; + return 1; + } + map< string, vector > names; + if(!DF.InitReadNameTables(names)) + { + cerr << "Could not get Names" << endl; + return 1; + } + string input; + DF.ForceResume(); + cout << "\nSelect Name to search or q to Quit" << endl; + getline (cin, input); + while(input != "q"){ + for( map< string, vector >::iterator it = names.begin();it != names.end(); it++){ + for(uint32_t i = 0; i < it->second.size(); i++){ + uint32_t found = input.find(it->second[i]); + if(found != string::npos){ + cout << it->first << " " << it->second[i] << " " << setfill('0') << setw(8) << hex << i << endl; + } + } + } + DF.Resume(); + getline(cin,input); + } + DF.Detach(); + DF.FinishReadNameTables(); + #ifndef LINUX_BUILD + cout << "Done. Press any key to continue" << endl; + cin.ignore(); + #endif + return 0; +}