diff options
Diffstat (limited to 'needs_porting/drawtile.cpp')
| -rw-r--r-- | needs_porting/drawtile.cpp | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/needs_porting/drawtile.cpp b/needs_porting/drawtile.cpp new file mode 100644 index 00000000..72f2beb0 --- /dev/null +++ b/needs_porting/drawtile.cpp @@ -0,0 +1,315 @@ +// + +#include <iostream> +#include <vector> +#include <map> +#include <cstdlib> +#include <limits> +using namespace std; + +#include <conio.h> + + +#include <DFHack.h> +#include <DFTileTypes.h> + +//Avoid including Windows.h because it causes name clashes +extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long milliseconds); + +//Trim +#define WHITESPACE " \t\r\n" +inline string trimr(const string & s, const string & t = WHITESPACE) +{ + string d (s); + string::size_type i (d.find_last_not_of (t)); + if (i == string::npos) + return ""; + else + return d.erase (d.find_last_not_of (t) + 1) ; +} +inline string triml(const string & s, const string & t = WHITESPACE) +{ + string d (s); + return d.erase (0, s.find_first_not_of (t)) ; +} +inline string trim(const string & s, const string & t = WHITESPACE) +{ + string d (s); + return triml(trimr(d, t), t); +} + +void printtiletype( int i ){ + printf("%s\n%4i ; %-13s ; %-11s ; %c ; %-12s ; %s\n", + ( DFHack::tileTypeTable[i].name ? DFHack::tileTypeTable[i].name : "[invalid tile]" ), + i, + ( DFHack::tileTypeTable[i].name ? DFHack::TileShapeString[ DFHack::tileTypeTable[i].shape ] : "" ), + ( DFHack::tileTypeTable[i].name ? DFHack::TileMaterialString[ DFHack::tileTypeTable[i].material ] : "" ), + ( DFHack::tileTypeTable[i].variant ? '0'+ DFHack::tileTypeTable[i].variant : ' ' ), + ( DFHack::tileTypeTable[i].special ? DFHack::TileSpecialString[ DFHack::tileTypeTable[i].special ] : "" ), + ( DFHack::tileTypeTable[i].direction.whole ? DFHack::tileTypeTable[i].direction.getStr() : "" ), + 0 + ); +} + + +int main (void) +{ + int32_t x,y,z,tx,ty; + //DFHack::designations40d designations; + DFHack::tiletypes40d tiles; + //DFHack::t_temperatures temp1,temp2; + uint32_t x_max,y_max,z_max; + int32_t oldT, newT; + int count, dirty; + + //Brush defaults + DFHack::TileShape BrushClass = DFHack::WALL; + DFHack::TileMaterial BrushMat = DFHack::tilematerial_invalid; + int BrushType = -1; + + DFHack::ContextManager DFMgr("Memory.xml"); + DFHack::Context *DF; + DFHack::Maps * Maps; + DFHack::Gui * Gui; + try + { + DF=DFMgr.getSingleContext(); + DF->Attach(); + Maps = DF->getMaps(); + Maps->Start(); + Maps->getSize(x_max,y_max,z_max); + Gui = DF->getGui(); + } + catch (exception& e) + { + cerr << e.what() << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + bool end = false; + cout << "Welcome to the Tile Drawing tool.\nType 'help' or ? for a list of available commands, 'q' to quit" << endl; + string mode = "wall"; + string command = ""; + + while(!end) + { + DF->Resume(); + + cout << endl << ":"; + getline(cin, command); + int ch = command[0]; + if(command.length()<=0) ch=0; + if( ((int)command.find("help")) >=0 ) ch='?'; //under windows, find was casting unsigned! + switch(ch) + { + case '?': + cout << "Modes:" << endl + << "O - draw Open Space" << endl + << "M - draw material only (shape unchanged)" << endl + << "m number - use Material value entered" << endl + << "r - use Rock/stone material" << endl + << "l - use Soil material" << endl + << "v - use Vein material" << endl + << "H - draw tile shape only (material unchanged)" << endl + << "h number - draw Tile Shape value entered" << endl + << "w - draw Wall tiles" << endl + << "f - draw Floor tiles" << endl + << "t number - draw exact tile type entered" << endl + << "Commands:" << endl + << "p - print tile shapes and materials, and current brush" << endl + << "P - print all tile types" << endl + << "q - quit" << endl + << "help OR ? - print this list of commands" << endl + << "d - being drawing" << endl + << endl + << "Usage:\nChoose a mode (default is walls), then enter 'd' to being drawing.\nMove the cursor in DF wherever you want to draw.\nPress any key to pause drawing." << endl; + break; + case 'p': + //Classes + printf("\nTile Type Classes:\n"); + for(int i=0;i<DFHack::tileshape_count;++i) + { + printf("%4i ; %s\n", i, DFHack::TileShapeString[i] ,0 ); + } + //Materials + printf("\nTile Type Materials:\n"); + for(int i=0;i<DFHack::tilematerial_count;++i) + { + printf("%4i ; %s\n", i, DFHack::TileMaterialString[i] ,0 ); + } + //fall through... + case 10: + case 13: + case 0: + //Print current cursor & brush settings. + cout << "\nCurrent Brush:\n"; + cout << "tile = "; + if(BrushClass<0) cout<<"(not drawing)"; else cout<<DFHack::TileShapeString[BrushClass]; cout << endl; + cout << "mat = "; + if(BrushMat<0) cout<<"(not drawing)"; else cout<<DFHack::TileMaterialString[BrushMat]; cout << endl; + cout << "type = "; + if(BrushType<0){ + cout<<"(not drawing)"; + }else{ + printtiletype(BrushType); + } + break; + case 'P': + cout << "\nAll Valid Tile Types:\n"; + for(int i=0;i<TILE_TYPE_ARRAY_LENGTH;++i) + { + if( DFHack::tileTypeTable[i].name ) + printtiletype(i); + } + case 'w': + BrushType=-1; + BrushClass = DFHack::WALL; + cout << "Tile brush shape set to Wall." << endl; + break; + case 'f': + BrushType=-1; + BrushClass = DFHack::FLOOR; + cout << "Tile brush shape set to Floor." << endl; + break; + case 'h': + BrushType=-1; + BrushClass = (DFHack::TileShape)atol( command.c_str()+1 ); + cout << "Tile brush shape set to " << BrushClass << endl; + break; + case 'M': + BrushClass = DFHack::tileshape_invalid; + cout << "Tile brush will not draw tile shape." << endl; + break; + case 'r': + BrushType=-1; + BrushMat = DFHack::STONE; + cout << "Tile brush material set to Rock." << endl; + break; + case 'l': + BrushType=-1; + BrushMat = DFHack::SOIL; + cout << "Tile brush material set to Soil." << endl; + break; + case 'v': + BrushType=-1; + BrushMat = DFHack::VEIN; + cout << "Tile brush material set to Vein." << endl; + break; + case 'm': + BrushType=-1; + BrushMat = (DFHack::TileMaterial)atol( command.c_str()+1 ); + cout << "Tile brush material set to " << BrushMat << endl; + break; + case 'H': + BrushMat = DFHack::tilematerial_invalid; + cout << "Tile brush will not draw material." << endl; + break; + case 'O': + BrushType=-1; + BrushClass = DFHack::EMPTY; + BrushMat = DFHack::AIR; + cout << "Tile brush will draw Open Space." << endl; + break; + case 't': + BrushClass = DFHack::tileshape_invalid ; + BrushMat = DFHack::tilematerial_invalid; + BrushType = atol( command.c_str()+1 ); + cout << "Tile brush type set to:" << endl; + printtiletype(BrushType); + break; + case 'q': + end = true; + cout << "Bye!" << endl; + break; + case 'd': + { + count=0; + cout << "Beginning to draw at cursor." << endl << "Press any key to stop drawing." << endl; + //DF->Suspend(); + kbhit(); //throw away, just to be sure. + for(;;) + { + if(!Maps->Start()) + { + cout << "Can't see any DF map loaded." << endl; + break; + } + if(!Gui->getCursorCoords(x,y,z)) + { + cout << "Can't get cursor coords! Make sure you have a cursor active in DF." << endl; + break; + } + //cout << "cursor coords: " << x << "/" << y << "/" << z << endl; + tx=x%16; ty=y%16; + + if(!Maps->isValidBlock(x/16,y/16,z)) + { + cout << "Invalid block." << endl; + break; + } + + //Read the tiles. + dirty=0; + Maps->ReadTileTypes((x/16),(y/16),z, &tiles); + oldT = tiles[tx][ty]; + + newT = -1; + if( 0<BrushType ){ + //Explicit tile type set. Trust the user. + newT = BrushType; + }else if( 0==BrushMat && 0==BrushClass ){ + //Special case, Empty Air. + newT = 32; + }else if( BrushMat>=0 && BrushClass>=0 && ( BrushClass != DFHack::tileTypeTable[oldT].shape || BrushMat != DFHack::tileTypeTable[oldT].material) ){ + //Set tile material and class + newT = DFHack::findTileType(BrushClass,BrushMat, DFHack::tileTypeTable[oldT].variant , DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); + if(newT<0) newT = DFHack::findTileType(BrushClass,BrushMat, DFHack::tilevariant_invalid, DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); + if(newT<0) newT = DFHack::findTileType(BrushClass,BrushMat, DFHack::tilevariant_invalid , DFHack::tileTypeTable[oldT].special , (uint32_t)0 ); + }else if( BrushMat<0 && BrushClass>=0 && BrushClass != DFHack::tileTypeTable[oldT].shape ){ + //Set current tile class only, as accurately as can be expected + newT = DFHack::findSimilarTileType(oldT,BrushClass); + }else if( BrushClass<0 && BrushMat>=0 && BrushMat != DFHack::tileTypeTable[oldT].material ){ + //Set current tile material only + newT = DFHack::findTileType(DFHack::tileTypeTable[oldT].shape,BrushMat, DFHack::tileTypeTable[oldT].variant , DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); + if(newT<0) newT = DFHack::findTileType(DFHack::tileTypeTable[oldT].shape,BrushMat, DFHack::tilevariant_invalid , DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); + if(newT<0) newT = DFHack::findTileType(DFHack::tileTypeTable[oldT].shape,BrushMat, DFHack::tilevariant_invalid , DFHack::tileTypeTable[oldT].special , (uint32_t)0 ); + } + //If no change, skip it (couldn't find a good tile type, or already what we want) + if ( newT > 0 && oldT != newT ){ + //Set new tile type + tiles[tx][ty] = newT; + dirty=-1; + } + //If anything was changed, write it all. + if (dirty) + { + //Maps->WriteDesignations(x/16,y/16,z/16, &designations); + Maps->WriteTileTypes(x/16,y/16,z, &tiles); + printf("(%4d,%4d,%4d)",x,y,z); + ++count; + } + + Maps->Finish(); + + Sleep(10); + if( kbhit() ) break; + } + cin.clear(); + cout << endl << count << " tiles were drawn." << endl << "Drawing halted. Entering command mode." << endl; + } + continue; + break; + default: + cout << "Unknown command: " << command << endl; + } + + } + DF->Detach(); + #ifndef LINUX_BUILD + cout << "Done. Press any key to continue" << endl; + cin.ignore(); + #endif + return 0; +} |
