Start writing the new coordinates classes.
I'm not sure I'm going down the right path, so I'm committing what I have so far and putting this on hold.
This commit is contained in:
parent
67e8ceefa3
commit
0bae01fd3f
4 changed files with 190 additions and 0 deletions
|
@ -70,6 +70,7 @@ add_executable(${PROJECT_NAME}
|
||||||
src/worldsizenotifiable.cpp
|
src/worldsizenotifiable.cpp
|
||||||
src/worlditems.cpp
|
src/worlditems.cpp
|
||||||
src/moveable.cpp
|
src/moveable.cpp
|
||||||
|
src/singlecoordinate.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} SYSTEM
|
target_include_directories(${PROJECT_NAME} SYSTEM
|
||||||
|
|
53
src/coordinates.hpp
Normal file
53
src/coordinates.hpp
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||||
|
|
||||||
|
This file is part of MyCurry.
|
||||||
|
|
||||||
|
MyCurry 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.
|
||||||
|
|
||||||
|
MyCurry 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 MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "vector.hpp"
|
||||||
|
#include "singlecoordinate.hpp"
|
||||||
|
|
||||||
|
namespace vwr {
|
||||||
|
template <>
|
||||||
|
struct VectorWrapperInfo<std::array<::curry::SingleCoordinate, 2>> {
|
||||||
|
enum { dimensions = 2 };
|
||||||
|
typedef ::curry::SingleCoordinate scalar_type;
|
||||||
|
typedef std::array<scalar_type, dimensions> vector_type;
|
||||||
|
static scalar_type& get_at (size_t parIndex, vector_type& parVector) {
|
||||||
|
return parVector[parIndex];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} //namespace vwr
|
||||||
|
|
||||||
|
namespace curry {
|
||||||
|
using vec2c = vwr::Vec<std::array<SingleCoordinate, 2>>;
|
||||||
|
|
||||||
|
inline vec2i to_screen_coordinates (vec2c parVec, const vec2i& parWorldOffset, vec2us parTileSize) {
|
||||||
|
return vec2i(
|
||||||
|
parVec.x().screen_coordinate(parWorldOffset.x(), parTileSize.x()),
|
||||||
|
parVec.y().screen_coordinate(parWorldOffset.y(), parTileSize.y())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline vec2us to_tiles (vec2c parVec) {
|
||||||
|
return vec2us(
|
||||||
|
parVec.x().tile(),
|
||||||
|
parVec.y().tile()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} //namespace curry
|
26
src/singlecoordinate.cpp
Normal file
26
src/singlecoordinate.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||||
|
|
||||||
|
This file is part of MyCurry.
|
||||||
|
|
||||||
|
MyCurry 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.
|
||||||
|
|
||||||
|
MyCurry 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 MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "singlecoordinate.hpp"
|
||||||
|
#include "coordinates.hpp"
|
||||||
|
|
||||||
|
namespace curry {
|
||||||
|
static_assert(implem::Log2<256>::result == 8, "Wrong logarithm result");
|
||||||
|
static_assert(implem::Log2<255>::result == 7, "Wrong logarithm result");
|
||||||
|
} //namespace curry
|
110
src/singlecoordinate.hpp
Normal file
110
src/singlecoordinate.hpp
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||||
|
|
||||||
|
This file is part of MyCurry.
|
||||||
|
|
||||||
|
MyCurry 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.
|
||||||
|
|
||||||
|
MyCurry 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 MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "vector.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cassert>
|
||||||
|
#include <ciso646>
|
||||||
|
|
||||||
|
namespace curry {
|
||||||
|
namespace implem {
|
||||||
|
template <uint32_t V, uint32_t R=0, uint32_t I=5, bool=(I>0)>
|
||||||
|
struct Log2;
|
||||||
|
|
||||||
|
template <uint32_t V, uint32_t R, uint32_t I>
|
||||||
|
struct Log2<V, R, I, true> {
|
||||||
|
static constexpr const uint32_t b[5] = {0x2, 0xc, 0xf0, 0xff00, 0xffff0000};
|
||||||
|
static constexpr const uint32_t S[5] = {1, 2, 4, 8, 16};
|
||||||
|
enum {
|
||||||
|
result = Log2<(V & b[I - 1] ? V >> S[I - 1] : V), (V & b[I - 1] ? R | S[I - 1] : R), I - 1>::result
|
||||||
|
};
|
||||||
|
};
|
||||||
|
template <uint32_t V, uint32_t R, uint32_t I>
|
||||||
|
struct Log2<V, R, I, false> {
|
||||||
|
enum {
|
||||||
|
result = R
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <uint32_t V>
|
||||||
|
struct NextPow2 {
|
||||||
|
static_assert(V > 0, "V must be greater than zero");
|
||||||
|
enum {
|
||||||
|
result = (1U << Log2<V - 1>::result) + 1
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} //namespace implem
|
||||||
|
|
||||||
|
class SingleCoordinate {
|
||||||
|
public:
|
||||||
|
SingleCoordinate() = default;
|
||||||
|
SingleCoordinate (const SingleCoordinate&) = default;
|
||||||
|
explicit SingleCoordinate (uint32_t parTile);
|
||||||
|
SingleCoordinate (uint32_t parTile, uint32_t parOffset);
|
||||||
|
~SingleCoordinate() noexcept = default;
|
||||||
|
|
||||||
|
int32_t screen_coordinate (int32_t parWorldOffset, uint32_t parTileSize) const;
|
||||||
|
uint32_t tile() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr const auto MaxTileSize = 128U;
|
||||||
|
static constexpr const auto OffsetBits = implem::Log2<MaxTileSize>::result;
|
||||||
|
static constexpr const auto OffsetMask = implem::NextPow2<MaxTileSize>::result - 1;
|
||||||
|
|
||||||
|
uint32_t m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline int32_t SingleCoordinate::screen_coordinate (int32_t parWorldOffset, uint32_t parTileSize) const {
|
||||||
|
assert(parTileSize <= MaxTileSize);
|
||||||
|
return ((m_data - parWorldOffset) & OffsetMask) +
|
||||||
|
(static_cast<uint32_t>(m_data - parWorldOffset) >> OffsetBits) * parTileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t SingleCoordinate::tile() const {
|
||||||
|
int beyond_tile;
|
||||||
|
const int offset = m_data & OffsetMask;
|
||||||
|
asm(
|
||||||
|
"xorl %%eax,%%eax\n\t"
|
||||||
|
"subl %1,%%eax\n\t"
|
||||||
|
"xorl %%eax,%%eax\n\t"
|
||||||
|
"adcl %%eax,0\n\t"
|
||||||
|
"movl %%eax,%0"
|
||||||
|
:"=r"(beyond_tile)
|
||||||
|
:"r"(offset)
|
||||||
|
:"%eax"
|
||||||
|
);
|
||||||
|
assert(0 == beyond_tile or 1 == beyond_tile);
|
||||||
|
return (m_data >> OffsetBits) + beyond_tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleCoordinate::SingleCoordinate (uint32_t parTile) :
|
||||||
|
m_data(parTile << OffsetBits)
|
||||||
|
{
|
||||||
|
assert(this->tile() == parTile);
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleCoordinate::SingleCoordinate (uint32_t parTile, uint32_t parOffset) :
|
||||||
|
m_data((parTile << OffsetBits) + (parOffset & OffsetMask))
|
||||||
|
{
|
||||||
|
assert((not parOffset and this->tile() == parTile) or (this->tile() == parTile + 1));
|
||||||
|
assert((m_data bitand OffsetMask) == parOffset);
|
||||||
|
}
|
||||||
|
} //namespace curry
|
Loading…
Reference in a new issue