Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "MapFileWriter.hpp"
- #include <Exception.hpp>
- #include <TmxParser/Tmx.h>
- #include <sstream>
- #include <algorithm>
- #include <Map.hpp>
- #include <iostream>
- namespace zelda
- {
- namespace utility
- {
- inline void tolower(std::string& str)
- {
- std::transform(str.begin(), str.end(), str.begin(), ::tolower);
- }
- }
- namespace io
- {
- MapFileWriter::MapFileWriter(const Uint8* data, const Uint64 length)
- : base(data, length)
- {}
- MapFileWriter::MapFileWriter(const std::string &filepath)
- : base(filepath)
- {}
- struct TileFlags
- {
- bool Horizontal:1;
- bool Vertical:1;
- bool Diagonal:1;
- };
- void MapFileWriter::fromTMX(const std::string &filepath)
- {
- Tmx::Map map;
- map.ParseFile(filepath);
- if (map.HasError())
- {
- std::stringstream err;
- err << "error in Tmx::Parser : " << (int)map.GetErrorCode() << ": " << map.GetErrorText() << std::endl;
- throw zelda::error::Exception(err.str());
- }
- base::writeUInt32(Map::MAGIC_NUMBER);
- base::writeUInt32(Map::VERSION);
- base::writeUInt16(0xFEFF);
- base::writeUInt32(map.GetWidth()*map.GetTileWidth());
- base::writeUInt32(map.GetHeight()*map.GetTileHeight());
- base::writeUInt32(map.GetTileWidth());
- base::writeUInt32(map.GetTileHeight());
- base::writeUByte(map.GetOrientation()); // will probably go unused but you never know
- base::writeUInt32(map.GetTilesets().size());
- Uint64 layerCountOffset = base::position();
- base::writeUInt32(map.GetLayers().size() - 1);
- // Align to 32bytes for Wii/GCN support
- base::seek((m_position + 0x1F) & ~0x1F, base::Beginning);
- for (Tmx::Tileset* tileset : map.GetTilesets())
- {
- std::string path = tileset->GetImage()->GetSource();
- path = path.substr(path.find_last_of("/") + 1, (path.size() - path.find_last_of("/")) - 1);
- base::writeString(path);
- }
- // Align to 32bytes for Wii/GCN support
- base::seek((m_position + 0x1F) & ~0x1F, base::Beginning);
- Tmx::Layer* colLayer = NULL;
- Uint32 layerCount = 0;
- for (Tmx::Layer* layer : map.GetLayers())
- {
- std::string name = (std::string)layer->GetName();
- utility::tolower(name);
- if (!name.compare("collision"))
- {
- if (!colLayer)
- colLayer = layer;
- else
- throw "Too many collision layers, The map can have at most 1 Collision layer, please remove the extraneous layers";
- continue;
- }
- int tileCount = 0;
- for (int y = 0; y < layer->GetHeight(); y++)
- {
- for (int x = 0; x < layer->GetWidth(); x++)
- {
- if (layer->GetTileTilesetIndex(x, y) == -1)
- continue;
- tileCount++;
- }
- }
- if (tileCount == 0)
- continue;
- layerCount++;
- base::writeBool(layer->IsVisible());
- base::writeUInt32(layer->GetZOrder());
- //base::writeUInt32(layer->GetProperties().GetSize());
- base::writeUInt32(tileCount);
- // Align to 32bytes for Wii/GCN support
- base::seek((m_position + 0x1F) & ~0x1F, base::Beginning);
- for (int y = 0; y < layer->GetHeight(); y++)
- {
- for (int x = 0; x < layer->GetWidth(); x++)
- {
- if (layer->GetTileTilesetIndex(x, y) == -1)
- continue;
- Tmx::Tile& tile = (Tmx::Tile&)layer->GetTile(x, y);
- base::writeInt32(tile.GetId());
- base::writeUInt32(layer->GetTileTilesetIndex(x, y));
- TileFlags flags;
- flags.Horizontal = layer->IsTileFlippedHorizontally(x, y);
- flags.Vertical = layer->IsTileFlippedVertically(x, y);
- flags.Diagonal = layer->IsTileFlippedDiagonally(x, y);
- base::writeUBytes((Uint8*)&flags, 1);
- base::writeUInt16(x*map.GetTileWidth());
- base::writeUInt16(y*map.GetTileHeight());
- }
- }
- base::seek((m_position + 0x1F) & ~0x1F, base::Beginning);
- }
- // Write the collision data
- for (int y = 0; y < map.GetHeight(); y++)
- {
- for (int x = 0; x < map.GetWidth(); x++)
- {
- if (colLayer)
- {
- if (colLayer->GetTileTilesetIndex(x, y) != -1)
- base::writeByte(0x00);
- else
- base::writeByte(0xFF);
- }
- else
- base::writeByte(0xFF);
- }
- }
- base::seek(layerCountOffset, base::Beginning);
- base::writeUInt32(layerCount);
- std::cout << layerCount << std::endl;
- // Finally save the map
- base::save();
- }
- void MapFileWriter::setFilepath(const std::string& filepath)
- {
- base::m_filepath = filepath;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement