summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/anim-atlas.cpp63
-rw-r--r--test/bitmask.cpp14
-rw-r--r--test/bitmask.embed.inc18
3 files changed, 42 insertions, 53 deletions
diff --git a/src/anim-atlas.cpp b/src/anim-atlas.cpp
index 650ca41e..3386de06 100644
--- a/src/anim-atlas.cpp
+++ b/src/anim-atlas.cpp
@@ -16,6 +16,29 @@ static constexpr inline auto rot_count = size_t(rotation_COUNT);
static_assert(std::size(name_array) == rot_count);
static_assert(rot_count == 8);
+namespace {
+
+constexpr uint8_t amin = 32;
+
+CORRADE_ALWAYS_INLINE void make_bitmask_impl(const ImageView2D& tex, BitArray& array)
+{
+ array.resetAll(); // slow
+ const auto pixels = tex.pixels();
+ fm_soft_assert(tex.pixelSize() == 4);
+ fm_soft_assert(pixels.stride()[1] == 4);
+
+ const auto* const src = (const unsigned char*)pixels.data();
+ const auto stride = (size_t)pixels.stride()[0];
+ const auto size = pixels.size();
+ const auto width = size[1], height = size[0];
+
+ for (auto j = 0u; j < height; j++)
+ for (auto i = 0u; i < width; i++)
+ array.set((height - j - 1)*width + i, src[(j*stride + i*4)+3] >= amin);
+}
+
+} // namespace
+
uint8_t anim_atlas::rotation_to_index(StringView name)
{
for (uint8_t i = 0; i < rot_count; i++)
@@ -135,45 +158,7 @@ auto anim_atlas::frame_quad(const Vector3& center, rotation r, size_t i) const n
void anim_atlas::make_bitmask_(const ImageView2D& tex, BitArray& array)
{
- // todo! decompose into a C function that can use __restrict
- const auto pixels = tex.pixels();
- const auto size = pixels.size();
- const auto width = size[1], height = size[0],
- stride = (size_t)pixels.stride()[0], width0 = width & ~7u;
- const auto* const data = (const unsigned char*)pixels.data();
- auto* const dest = (unsigned char*)array.data();
-
- fm_soft_assert(tex.pixelSize() == 4);
- fm_soft_assert(pixels.stride()[1] == 4);
-
- for (auto j = 0uz; j < height; j++)
- {
- constexpr unsigned char amin = 32;
- auto i = 0uz;
- for (; i < width0; i += 8)
- {
- const auto src_idx = (j*stride + i*4)+3, dst_idx = (height-j-1)*width+i >> 3;
- const unsigned char* buf = data + src_idx;
- auto value = (unsigned char)(
- (unsigned char)(buf[0*4] >= amin) << 0 |
- (unsigned char)(buf[1*4] >= amin) << 1 |
- (unsigned char)(buf[2*4] >= amin) << 2 |
- (unsigned char)(buf[3*4] >= amin) << 3 |
- (unsigned char)(buf[4*4] >= amin) << 4 |
- (unsigned char)(buf[5*4] >= amin) << 5 |
- (unsigned char)(buf[6*4] >= amin) << 6 |
- (unsigned char)(buf[7*4] >= amin) << 7);
- dest[dst_idx] = value;
- }
- if (i < width)
- {
- dest[(height-j-1)*width+i >> 3] = 0;
- do {
- unsigned char alpha = data[(j*stride + i*4)+3];
- array.set((height-j-1)*width + i, alpha >= amin);
- } while (++i < width);
- }
- }
+ return make_bitmask_impl(tex, array);
}
BitArray anim_atlas::make_bitmask(const ImageView2D& tex)
diff --git a/test/bitmask.cpp b/test/bitmask.cpp
index f6abea14..d0b6c4d8 100644
--- a/test/bitmask.cpp
+++ b/test/bitmask.cpp
@@ -3,7 +3,6 @@
#include "src/anim-atlas.hpp"
#include "loader/loader.hpp"
#include <Corrade/Containers/ArrayView.h>
-#include <Corrade/Containers/StridedArrayView.h>
#include <mg/Functions.h>
#include <mg/ImageData.h>
@@ -16,12 +15,12 @@ const unsigned char src[] = {
};
constexpr auto data_nbytes = arraySize(src);
-constexpr auto size = Vector2i{8, 16};
-static_assert(size_t{size.product()+7}/8 <= data_nbytes);
+constexpr auto size = Vector2i{21, 52};
+//static_assert(size_t{size.product()+7}/8 <= data_nbytes);
void bitmask_test()
{
- auto img = loader.texture(loader.SCENERY_PATH, "door-close"_s);
+ auto img = loader.texture(loader.SCENERY_PATH, "control-panel"_s);
auto bitmask = anim_atlas::make_bitmask(img);
fm_assert(bitmask.size() >= size_t{size.product()});
fm_assert(img.pixelSize() == 4);
@@ -40,8 +39,11 @@ void bitmask_test()
const auto len = Math::min(data_nbytes, (size_t)bitmask.size()+7 >> 3);
fm_assert(arraySize(src) >= len);
for (auto i = 0uz; i < len; i++)
- if ((unsigned char)bitmask.data()[i] != src[i])
- fm_abort("wrong value at byte %zu, should be' 0x%02hhx'", i, src[i]);
+ {
+ auto a = (unsigned char)bitmask.data()[i];
+ if (a != src[i])
+ fm_abort("wrong value 0x%02hhx at byte %zu, should be' 0x%02hhx'", a, i, src[i]);
+ }
}
} // namespace
diff --git a/test/bitmask.embed.inc b/test/bitmask.embed.inc
index 1dcc633e..2b1f7a5f 100644
--- a/test/bitmask.embed.inc
+++ b/test/bitmask.embed.inc
@@ -1,8 +1,10 @@
-0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+0x03,0x00,0xe0,0x01,0x00,0x7c,0x00,0x80,0x3f,0x00,0xf0,0x1f,0x00,0xfe,0x0f,
+0xc0,0xff,0x03,0xf8,0xff,0x01,0xff,0xff,0xe0,0xff,0x3f,0xfc,0xff,0x9f,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xff,0x1f,0xff,0xff,0x83,0xff,0x7f,0xe0,0xff,0x0f,0xf0,0xff,0x01,0xf8,
+0x3f,0x00,0xfe,0x07,0x00,0xff,0x00,0x80,0x1f,0x00,0xc0,0x03,0x00,0x70,0x00,
+0x00,0xb8,