#ifndef id3F4AB2FAA29D4A0FA87760E61F0762C0 #define id3F4AB2FAA29D4A0FA87760E61F0762C0 #include "doorkeeper/primitivetypes.hpp" #include "doorkeeper/implem/vector.hpp" #include "doorkeeper/components/basemapsource.hpp" #include "doorkeeper/implem/maptypes.hpp" #include "doorkeeper/components/exception.hpp" #include #include #include #include #include #include #if !defined(NDEBUG) && !defined(WITH_TYLERMAP_WRITER) # define WITH_TYLERMAP_WRITER #endif namespace dkh { namespace implem { class TylerMapSourceBase { public: typedef std::istream::pos_type pos_type; explicit TylerMapSourceBase ( std::istream* parStream ); ~TylerMapSourceBase ( void ); dk::HashType layerTypeHash ( int parIndex ) const; void chainedMaps ( std::vector& parOut ) const; dk::MapTypes mapType ( void ) const; void parseMapHeaders ( uint32_t parDim, std::vector& parMapDims, std::vector& parTileDims ); private: struct LayerInfo; std::vector m_layers_info; dk::MapTypes m_map_type; std::map m_comments; std::string m_file_vendor; std::unique_ptr m_stream; pos_type m_stream_start; }; } //namespace implem template class TylerMapSource : private implem::TylerMapSourceBase, public dk::BaseMapSource { typedef implem::TylerMapSourceBase base_class; typedef base_class::pos_type pos_type; public: typedef dk::Vector coords; enum { MapDimensions = D }; TylerMapSource ( void ) = delete; TylerMapSource ( const TylerMapSource& ) = delete; TylerMapSource ( TylerMapSource&& ) = default; explicit TylerMapSource ( const char* parFilename ); explicit TylerMapSource ( const std::string& parFilename ); explicit TylerMapSource ( std::istream* parData ); virtual ~TylerMapSource ( void ) noexcept = default; virtual const coords& mapSize ( void ) const; virtual const coords& tileSize ( void ) const; virtual dk::MapTypes mapType ( void ) const; virtual int layersCount ( void ) const; virtual void chainedMaps ( std::vector& parOut ) const; virtual dk::HashType layerTypeHash ( int parIndex ) const; private: void parse_map_data ( void ); virtual void fetch_raw ( char* parOut, const coords& parFrom, const coords& parTo, std::size_t parSize ); coords m_map_size; coords m_tile_size; uint16_t m_map_version_major; uint16_t m_map_version_minor; uint8_t m_layer_count; }; #if defined(WITH_TYLERMAP_WRITER) class TylerMapWriter { public: TylerMapWriter ( void ) = delete; TylerMapWriter ( const TylerMapWriter& ) = delete; TylerMapWriter ( TylerMapWriter&& ) = default; private: std::unique_ptr m_stream; }; #endif class InvalidMapFileException : public dk::DoorKeeperException { }; class InvalidMapDimensionsException : public dk::DoorKeeperException { }; namespace implem { struct TylerMapHeader { uint32_t signature; uint32_t file_size; uint16_t version_major; uint16_t version_minor; uint8_t layer_count; uint8_t map_type; uint8_t hashing_algorithm; uint8_t dimensions; uint32_t dimensions_start; uint32_t comment_start; uint32_t layer_start; } __attribute__((packed, aligned(__alignof__(uint32_t)))); struct TylerMapLayerHeader { uint32_t layer_length; uint32_t layer_format; } __attribute__((packed, aligned(__alignof__(uint32_t)))); void read_header ( std::istream& parStream, TylerMapHeader& parHeader ); void read_layer_header ( std::istream& parStream, TylerMapLayerHeader& parHeader ); void read_dimensions ( std::istream& parStream, uint32_t parDimensions, std::vector& parMap, std::vector& parTile ); } //namespace implem } //namespace dkh #include "doorkeeper/implem/tylermapsource.inl" #endif