diff options
-rw-r--r-- | tools/tmxcopy/Makefile | 5 | ||||
-rw-r--r-- | tools/tmxcopy/map.cpp | 70 | ||||
-rw-r--r-- | tools/tmxcopy/map.hpp | 18 | ||||
-rw-r--r-- | tools/tmxcopy/tmxcollide.cpp | 104 |
4 files changed, 196 insertions, 1 deletions
diff --git a/tools/tmxcopy/Makefile b/tools/tmxcopy/Makefile index 975e1980..d061f36e 100644 --- a/tools/tmxcopy/Makefile +++ b/tools/tmxcopy/Makefile @@ -3,7 +3,7 @@ CFLAGS=-g -ggdb -O0 -Wall -c `pkg-config --cflags libxml-2.0` LDFLAGS=`pkg-config --libs libxml-2.0` SOURCES_UTILS=base64.cpp map.cpp xmlutils.cpp zlibutils.cpp OBJECTS_UTILS=$(SOURCES_UTILS:.cpp=.o) -EXECUTABLES=tmxcopy tmx_random_fill +EXECUTABLES=tmxcopy tmx_random_fill tmxcollide all: $(SOURCES_UTILS) $(EXECUTABLES) make clean @@ -14,6 +14,9 @@ tmxcopy: tmxcopy.o $(OBJECTS_UTILS) tmx_random_fill: tmx_random_fill.o $(OBJECTS_UTILS) $(CC) $(LDFLAGS) tmx_random_fill.o $(OBJECTS_UTILS) -o $@ +tmxcollide: tmxcollide.o $(OBJECTS_UTILS) + $(CC) $(LDFLAGS) tmxcollide.o $(OBJECTS_UTILS) -o $@ + .cpp.o: $(CC) $(CFLAGS) $< -o $@ diff --git a/tools/tmxcopy/map.cpp b/tools/tmxcopy/map.cpp index 30f16a2d..109d1742 100644 --- a/tools/tmxcopy/map.cpp +++ b/tools/tmxcopy/map.cpp @@ -440,6 +440,76 @@ bool Map::randomFill(Map* templateMap, const std::string& destLayerName, return true; } +bool Map::translateAllLayers(Map* templateMap, const std::string& destLayerName, + const ConfigurationOptions& config) +{ + bool checkPassed = true; + if (templateMap->getNumberOfLayers() != 2) + { + std::cerr<<"Error: template should have exactly 2 layers"<<std::endl; + checkPassed = false; + } + if (!config.createMissingLayers && !getLayer(destLayerName)) + { + std::cerr<<"Error: target map has no layer named \""<<destLayerName<<"\""<<std::endl + <<"(and the command-line \"create layers\" option was not used)"<<std::endl; + checkPassed = false; + } + if (!checkPassed) return false; + + //FIXME - as is, this will add tilesets that are in the template but + //not used in the main map + std::map<int, int> tilesetTranslation = addAndTranslateTilesets(templateMap); + + //Lacking a better name, we'll say this is translating visible layers to collision + std::map<Tile, Tile> collisionTranslation; + + Layer* fromLayer = templateMap->getLayer(0); + Layer* toLayer = templateMap->getLayer(1); + for (int xy = (templateMap->getWidth() * templateMap->getHeight() -1); + xy >= 0; xy--) + { + Tile& fromTile = fromLayer->at(xy); + Tile& toTile = toLayer->at(xy); + if (!fromTile.empty()) + { + collisionTranslation[fromTile] = toTile; //FIXME - just getting it compiling so far + } + } + + /* Now apply that template to the game map */ + Layer* destLayer = getLayer(destLayerName); + if (!destLayer) + { + destLayer = new Layer(destLayerName, mWidth * mHeight); + mLayers.push_back(destLayer); + std::cout<<"Created new layer "<<destLayerName<<std::endl; + } + + for (std::vector<Layer*>::iterator layer = mLayers.begin(); + layer != mLayers.end(); + layer++) + { + if ((*layer)->getName() == destLayerName) + continue; + + for (int xy = mWidth * mHeight -1; xy >= 0; xy--) + { + Tile& fromTile = (*layer)->at(xy); + Tile& toTile = destLayer->at(xy); + std::map<Tile,Tile>::iterator iteratedTile = collisionTranslation.find(fromTile); + + if (iteratedTile != collisionTranslation.end()) + { + toTile = (*iteratedTile).second; + } + } + + } + + return true; +} + int Map::save(std::string filename) diff --git a/tools/tmxcopy/map.hpp b/tools/tmxcopy/map.hpp index 4b0ab59a..d6cd3d1a 100644 --- a/tools/tmxcopy/map.hpp +++ b/tools/tmxcopy/map.hpp @@ -78,6 +78,17 @@ struct Tile { return (tileset == -1); } + + /* This is to allow std::map<Tile,Tile> */ + bool operator< (const Tile& b) const + { + return ((tileset < b.tileset) || (index < b.index)); + } + + bool operator!= (const Tile& b) const + { + return ((tileset != b.tileset) || (index != b.index)); + } }; typedef std::vector<Tile> LayerTiles; @@ -131,6 +142,13 @@ class Map int destX, int destY, int destWidth, int destHeight, const ConfigurationOptions& config); + /** + * Translates a layer - using the template, generates collision from visible layers (for example). + * TODO - avoid confusion with the math term "translate" + */ + bool translateAllLayers(Map* templateMap, const std::string& destLayerName, + const ConfigurationOptions& config); + int save(std::string filename); int getNumberOfLayers() { return mLayers.size(); } diff --git a/tools/tmxcopy/tmxcollide.cpp b/tools/tmxcopy/tmxcollide.cpp new file mode 100644 index 00000000..2ce6f90b --- /dev/null +++ b/tools/tmxcopy/tmxcollide.cpp @@ -0,0 +1,104 @@ +/* + * TMXTranslate / TMXCollide + * Copyright (C) 2007 Philipp Sehmisch + * Copyright (C) 2009 Steve Cotton + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <iostream> +#include <string> +#include <unistd.h> + +#include "map.hpp" + +void printUsage() +{ + std::cerr<<"Usage: tmxcollide [-c] mapFile destLayer templateFile [-o outfile]"<<std::endl + <<" -c create layers, if they don't already exist in the target"<<std::endl + <<" -o save results to outfile, instead of overwriting the original"<<std::endl + <<std::endl + <<"Using the template, translate visible layers to the collision layer"<<std::endl + <<"TODO - more help here"<<std::endl; +} + +int main(int argc, char * argv[] ) +{ + ConfigurationOptions config = {0}; + std::string outFile; + + int opt; + while ((opt = getopt(argc, argv, "co:")) != -1) + { + switch (opt) + { + case 'c': + config.createMissingLayers = true; + break; + case 'o': + if (optarg) + { + outFile = optarg; + } else { + printUsage(); + return -1; + } + break; + case '?': + std::cerr<<"Unrecognized option"<<std::endl; + printUsage(); + return -1; + } + } + + if ((argc-optind) < 3) + { + std::cerr<<"Too few args"<<std::endl; + printUsage(); + return -1; + } + if ((argc-optind) > 3) + { + std::cerr<<"Too many args"<<std::endl; + printUsage(); + return -1; + } + + std::string mapFile = argv[optind+0]; + std::string destLayer = argv[optind+1]; + std::string templateFile = argv[optind+2]; + if (outFile.empty()) + { + outFile = mapFile; + } + + try + { + Map* mainMap = new Map(mapFile); + Map* templateMap = new Map(templateFile); + if (mainMap->translateAllLayers(templateMap, destLayer, config)) + { + mainMap->save(outFile); + } else { + return -1; + } + delete mainMap; + delete templateMap; + } + catch (int) + { + return -1; + } +} |