Advertisement
Guest User

Untitled

a guest
Aug 8th, 2013
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.84 KB | None | 0 0
  1. #include "MapFileWriter.hpp"
  2. #include <Exception.hpp>
  3. #include <TmxParser/Tmx.h>
  4. #include <sstream>
  5. #include <algorithm>
  6. #include <Map.hpp>
  7. #include <iostream>
  8.  
  9. namespace zelda
  10. {
  11. namespace utility
  12. {
  13. inline void tolower(std::string& str)
  14. {
  15.     std::transform(str.begin(), str.end(), str.begin(), ::tolower);
  16. }
  17.  
  18. }
  19. namespace io
  20. {
  21.  
  22.  
  23. MapFileWriter::MapFileWriter(const Uint8* data, const Uint64 length)
  24.     : base(data, length)
  25. {}
  26.  
  27. MapFileWriter::MapFileWriter(const std::string &filepath)
  28.     : base(filepath)
  29. {}
  30.  
  31. struct TileFlags
  32. {
  33.     bool Horizontal:1;
  34.     bool Vertical:1;
  35.     bool Diagonal:1;
  36. };
  37.  
  38. void MapFileWriter::fromTMX(const std::string &filepath)
  39. {
  40.     Tmx::Map map;
  41.     map.ParseFile(filepath);
  42.     if (map.HasError())
  43.     {
  44.         std::stringstream err;
  45.         err << "error in Tmx::Parser : " << (int)map.GetErrorCode() << ": " << map.GetErrorText() << std::endl;
  46.         throw zelda::error::Exception(err.str());
  47.     }
  48.     base::writeUInt32(Map::MAGIC_NUMBER);
  49.     base::writeUInt32(Map::VERSION);
  50.     base::writeUInt16(0xFEFF);
  51.     base::writeUInt32(map.GetWidth()*map.GetTileWidth());
  52.     base::writeUInt32(map.GetHeight()*map.GetTileHeight());
  53.     base::writeUInt32(map.GetTileWidth());
  54.     base::writeUInt32(map.GetTileHeight());
  55.     base::writeUByte(map.GetOrientation()); // will probably go unused but you never know
  56.     base::writeUInt32(map.GetTilesets().size());
  57.     Uint64 layerCountOffset = base::position();
  58.     base::writeUInt32(map.GetLayers().size() - 1);
  59.     // Align to 32bytes for Wii/GCN support
  60.     base::seek((m_position + 0x1F) & ~0x1F, base::Beginning);
  61.  
  62.     for (Tmx::Tileset* tileset : map.GetTilesets())
  63.     {
  64.         std::string path = tileset->GetImage()->GetSource();
  65.         path = path.substr(path.find_last_of("/") + 1, (path.size() - path.find_last_of("/")) - 1);
  66.         base::writeString(path);
  67.     }
  68.  
  69.     // Align to 32bytes for Wii/GCN support
  70.     base::seek((m_position + 0x1F) & ~0x1F, base::Beginning);
  71.  
  72.     Tmx::Layer* colLayer = NULL;
  73.  
  74.     Uint32 layerCount = 0;
  75.     for (Tmx::Layer* layer : map.GetLayers())
  76.     {
  77.         std::string name = (std::string)layer->GetName();
  78.         utility::tolower(name);
  79.         if (!name.compare("collision"))
  80.         {
  81.             if (!colLayer)
  82.                 colLayer = layer;
  83.             else
  84.                 throw "Too many collision layers, The map can have at most 1 Collision layer, please remove the extraneous layers";
  85.             continue;
  86.         }
  87.  
  88.         int tileCount = 0;
  89.  
  90.         for (int y = 0; y < layer->GetHeight(); y++)
  91.         {
  92.             for (int x = 0; x < layer->GetWidth(); x++)
  93.             {
  94.                 if (layer->GetTileTilesetIndex(x, y) == -1)
  95.                     continue;
  96.                 tileCount++;
  97.             }
  98.         }
  99.  
  100.         if (tileCount == 0)
  101.             continue;
  102.  
  103.         layerCount++;
  104.         base::writeBool(layer->IsVisible());
  105.         base::writeUInt32(layer->GetZOrder());
  106.         //base::writeUInt32(layer->GetProperties().GetSize());
  107.  
  108.         base::writeUInt32(tileCount);
  109.  
  110.         // Align to 32bytes for Wii/GCN support
  111.         base::seek((m_position + 0x1F) & ~0x1F, base::Beginning);
  112.         for (int y = 0; y < layer->GetHeight(); y++)
  113.         {
  114.             for (int x = 0; x < layer->GetWidth(); x++)
  115.             {
  116.                 if (layer->GetTileTilesetIndex(x, y) == -1)
  117.                     continue;
  118.                 Tmx::Tile& tile = (Tmx::Tile&)layer->GetTile(x, y);
  119.                 base::writeInt32(tile.GetId());
  120.                 base::writeUInt32(layer->GetTileTilesetIndex(x, y));
  121.                 TileFlags flags;
  122.                 flags.Horizontal = layer->IsTileFlippedHorizontally(x, y);
  123.                 flags.Vertical = layer->IsTileFlippedVertically(x, y);
  124.                 flags.Diagonal = layer->IsTileFlippedDiagonally(x, y);
  125.                 base::writeUBytes((Uint8*)&flags, 1);
  126.                 base::writeUInt16(x*map.GetTileWidth());
  127.                 base::writeUInt16(y*map.GetTileHeight());
  128.             }
  129.         }
  130.  
  131.  
  132.         base::seek((m_position + 0x1F) & ~0x1F, base::Beginning);
  133.     }
  134.  
  135.  
  136.     // Write the collision data
  137.     for (int y = 0; y < map.GetHeight(); y++)
  138.     {
  139.         for (int x = 0; x < map.GetWidth(); x++)
  140.         {
  141.             if (colLayer)
  142.             {
  143.                 if (colLayer->GetTileTilesetIndex(x, y) != -1)
  144.                     base::writeByte(0x00);
  145.                 else
  146.                     base::writeByte(0xFF);
  147.             }
  148.             else
  149.                 base::writeByte(0xFF);
  150.         }
  151.     }
  152.  
  153.     base::seek(layerCountOffset, base::Beginning);
  154.     base::writeUInt32(layerCount);
  155.     std::cout << layerCount << std::endl;
  156.     // Finally save the map
  157.     base::save();
  158. }
  159.  
  160. void MapFileWriter::setFilepath(const std::string& filepath)
  161. {
  162.     base::m_filepath = filepath;
  163. }
  164.  
  165.  
  166. }
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement