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/worlditems.cpp
|
||||
src/moveable.cpp
|
||||
src/singlecoordinate.cpp
|
||||
)
|
||||
|
||||
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