summaryrefslogtreecommitdiff
path: root/needs_porting/drawtile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'needs_porting/drawtile.cpp')
-rw-r--r--needs_porting/drawtile.cpp315
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;
+}