136 lines
4.4 KiB
C++
136 lines
4.4 KiB
C++
/* Copyright 2015, Michele Santullo
|
|
* This file is part of DoorKeeper.
|
|
*
|
|
* DoorKeeper 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* DoorKeeper 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 DoorKeeper. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "doorkeeper/helpers/asciimapsource.hpp"
|
|
#include "doorkeeper/implem/compatibility.h"
|
|
#include "doorkeeper/helpers/typename.hpp"
|
|
#include "doorkeeper/helpers/typename_native.hpp"
|
|
#include "asciimap_parser.hpp"
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include <stdexcept>
|
|
#include <algorithm>
|
|
#include <sstream>
|
|
|
|
namespace dkh {
|
|
///-------------------------------------------------------------------------
|
|
///-------------------------------------------------------------------------
|
|
AsciiMapSource::AsciiMapSource (const char* parFilename, dk::MapTypes parMapType, const coords& parTileSize) :
|
|
m_mapSize(0),
|
|
m_pixel_conv(parTileSize),
|
|
m_mapType(parMapType)
|
|
{
|
|
std::ifstream src(parFilename);
|
|
parse_map_data(src);
|
|
}
|
|
|
|
///-------------------------------------------------------------------------
|
|
///-------------------------------------------------------------------------
|
|
AsciiMapSource::AsciiMapSource (const std::string& parFilename, dk::MapTypes parMapType, const coords& parTileSize) :
|
|
m_mapSize(0),
|
|
m_pixel_conv(parTileSize),
|
|
m_mapType(parMapType)
|
|
{
|
|
std::ifstream src(parFilename);
|
|
parse_map_data(src);
|
|
}
|
|
|
|
///-------------------------------------------------------------------------
|
|
///-------------------------------------------------------------------------
|
|
AsciiMapSource::AsciiMapSource (std::istream& parData, dk::MapTypes parMapType, const coords& parTileSize) :
|
|
m_mapSize(0),
|
|
m_pixel_conv(parTileSize),
|
|
m_mapType(parMapType)
|
|
{
|
|
parse_map_data(parData);
|
|
}
|
|
|
|
///-------------------------------------------------------------------------
|
|
///-------------------------------------------------------------------------
|
|
void AsciiMapSource::parse_map_data (std::istream& parSrc) {
|
|
typedef std::istream_iterator<char> DataIterator;
|
|
typedef boost::spirit::multi_pass<DataIterator> WrappedIterator;
|
|
|
|
parSrc >> std::noskipws;
|
|
|
|
auto first = WrappedIterator(DataIterator(parSrc));
|
|
auto last = WrappedIterator(DataIterator());
|
|
implem::AsciiMapGrammar<WrappedIterator, MapTileType> grammar(first);
|
|
const bool p = boost::spirit::qi::parse(
|
|
first,
|
|
last,
|
|
grammar,
|
|
m_wholedata
|
|
);
|
|
|
|
if (not p or last != first) {
|
|
throw std::runtime_error("Invalid data: can't parse file");
|
|
}
|
|
|
|
if (grammar.lengths.empty()) {
|
|
m_mapSize.x() = m_mapSize.y() = 0;
|
|
throw std::runtime_error("Invalid data: can't guess map size");
|
|
}
|
|
|
|
//Only look at the front. Besides a bug in spirit makes the other counts
|
|
//invalid, see
|
|
//http://boost.2283326.n4.nabble.com/Possible-bug-in-line-pos-iterator-td4636592.html
|
|
m_mapSize.x() = grammar.lengths.front();
|
|
m_mapSize.y() = m_wholedata.size() / m_mapSize.x();
|
|
}
|
|
|
|
const AsciiMapSource::coords& AsciiMapSource::mapSize() const {
|
|
return m_mapSize;
|
|
}
|
|
|
|
const AsciiMapSource::coords& AsciiMapSource::tileSize() const {
|
|
return m_pixel_conv.tile_size();
|
|
}
|
|
|
|
void AsciiMapSource::fetch_raw (char* parOut, const coords& parFrom, const coords& parTo, std::size_t parSize) {
|
|
const std::size_t from = parFrom.x() + parFrom.y() * m_mapSize.x();
|
|
const std::size_t to = parTo.x() - 1 + (parTo.y() - 1) * m_mapSize.x() + 1;
|
|
DK_ASSERT(to >= from);
|
|
DK_ASSERT(parSize / sizeof(MapTileType) == to - from);
|
|
std::copy(m_wholedata.begin() + from, m_wholedata.begin() + to, reinterpret_cast<MapTileType*>(parOut));
|
|
}
|
|
|
|
dk::MapTypes AsciiMapSource::mapType() const {
|
|
return m_mapType;
|
|
}
|
|
|
|
int AsciiMapSource::layersCount() const {
|
|
return 1;
|
|
}
|
|
|
|
void AsciiMapSource::chainedMaps (std::vector<std::string>&) const {
|
|
}
|
|
|
|
dk::HashType AsciiMapSource::layerTypeHash (int parIndex) const {
|
|
#if defined(DK_ASSERTIONS_ENABLED)
|
|
DK_ASSERT(0 == parIndex);
|
|
#else
|
|
(void)parIndex;
|
|
#endif
|
|
return dk::type_name_hash<int>();
|
|
}
|
|
|
|
const dk::PixelConv<2>& AsciiMapSource::pixel_conv() const {
|
|
return m_pixel_conv;
|
|
}
|
|
} //namespace dkh
|