Return icons as 24 bit RGB images.

Fetch function now accepts width/height parameters, which must be 16 for now.
Next I'm going to implement resizing to the specified width height.
This commit is contained in:
King_DuckZ 2018-09-13 19:54:56 +01:00
parent 1c8f07d51d
commit b0530a2be6
7 changed files with 130 additions and 52 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
build
tags

View file

@ -51,7 +51,7 @@ namespace {
#endif
const uint8_t alpha = (blue | green | red | black_flag ? 0xFF : 0x00);
std::cout << "RGBA: " << std::setw(3) << (int)red << '\t' << (int)green << '\t' << (int)blue << '\t' << (int)alpha << '\t' << (int)black_flag << std::setw(0) << '\n';
//std::cout << "RGBA: " << std::setw(3) << (int)red << '\t' << (int)green << '\t' << (int)blue << '\t' << (int)alpha << '\t' << (int)black_flag << std::setw(0) << '\n';
retval.push_back(blue);
retval.push_back(green);
retval.push_back(red);

View file

@ -8,33 +8,33 @@ namespace implem {
void draw_icons (
int icon_size,
const MemoryCard& mc,
std::array<nana::animation, 15>& icons,
std::vector<nana::animation>& icons,
nana::widget& wid
) {
assert(icon_size);
for (int z = 0; z < icons.size(); ++z) {
nana::frameset fset;
for (const auto& frame : icon_fetch(mc[z])) {
for (const auto& frame : icon_fetch(mc[z], icon_size, icon_size)) {
nana::paint::image img;
img.open(frame.data(), frame.size());
fset.push_back(img);
}
const int x = (16 + 2) * (z % 3);
const int y = (16 + 2) * (z / 3);
nana::animation& ani = icons[z];
ani.fps(3);
ani.push_back(fset);
ani.output(wid, nana::point(x, y));
ani.looped(true);
ani.play();
icons[z].push_back(fset);
}
}
} //namespace implem
grid_drawer_trigger::grid_drawer_trigger() = default;
grid_drawer_trigger::grid_drawer_trigger() {
std::cout << "constructing grid_drawer_trigger..." << std::endl;
m_icons.reserve(15);
for (int z = 0; z < 15; ++z) {
m_icons.emplace_back(3);
m_icons.back().looped(true);
m_icons.back().play();
}
}
void grid_drawer_trigger::attached (
nana::widget& widget,
@ -43,28 +43,52 @@ void grid_drawer_trigger::attached (
using nana::effects::edge_nimbus;
using nana::API::dev::enable_space_click;
using nana::API::tabstop;
using nana::API::effects_edge_nimbus;
using nana::API::dev::set_measurer;
m_graph = &graph;
m_widget = &widget;
nana::window wd = widget;
enable_space_click(widget, true);
tabstop(wd);
effects_edge_nimbus(wd, edge_nimbus::active);
effects_edge_nimbus(wd, edge_nimbus::over);
for (int z = 0; z < static_cast<int>(m_icons.size()); ++z) {
const int x = (16 + 2) * (z % 3);
const int y = (16 + 2) * (z / 3);
m_icons[z].output(*m_widget, nana::point(x, y));
}
}
void grid_drawer_trigger::detached() {
std::cout << "grid_drawer_trigger::detach()" << std::endl;
m_icons.clear();
m_widget = nullptr;
m_graph = nullptr;
m_is_ms_down = false;
m_icons_added = false;
}
void grid_drawer_trigger::set_memorycard (const MemoryCard* mc) {
m_memorycard = mc;
}
void grid_drawer_trigger::_m_draw_background (
nana::paint::graphics&,
bool is_mouse_down
) {
assert(m_memorycard);
//void grid_drawer_trigger::_m_draw_background (
// nana::paint::graphics&,
// bool is_mouse_down
//) {
// assert(m_memorycard);
// implem::draw_icons(16, *m_memorycard, m_icons, *m_widget);
//}
void grid_drawer_trigger::refresh (nana::paint::graphics& graph) {
assert(m_widget);
//draw background
if (not nana::API::dev::copy_transparent_background(*m_widget, graph))
graph.rectangle(true, m_widget->bgcolor());
if (m_memorycard and not m_icons_added) {
m_icons_added = true;
implem::draw_icons(16, *m_memorycard, m_icons, *m_widget);
}
}

View file

@ -22,16 +22,19 @@ public:
private:
virtual void attached(nana::widget&, nana::paint::graphics&) override;
virtual void detached() override;
virtual void refresh (nana::paint::graphics&) override;
//void _m_draw_title (nana::paint::graphics&, bool is_mouse_down, bool is_focus);
void _m_draw_background (nana::paint::graphics&, bool is_mouse_down);
//void _m_draw_background (nana::paint::graphics&, bool is_mouse_down);
//void _m_draw_border (nana::paint::graphics&, bool is_mouse_down);
std::array<nana::animation, 15> m_icons;
std::vector<nana::animation> m_icons;
nana::widget* m_widget{nullptr};
nana::paint::graphics* m_graph{nullptr};
const MemoryCard* m_memorycard{nullptr};
bool m_is_ms_down{false};
bool m_icons_added{false};
};
template <typename DrawerTrigger>

View file

@ -2,6 +2,7 @@
#include <cstdint>
#include <cassert>
#include <climits>
#include <algorithm>
namespace {
namespace bmp {
@ -28,56 +29,99 @@ namespace {
uint32_t biClrImportant = 0;
};
} //namespace bmp
void srgb_to_linear (std::vector<char>& data, int w, int h) {
assert(false);
}
void linear_to_srgb (std::vector<char>& data, int w, int h) {
assert(false);
}
std::vector<char> bilinear_resize (int in_w, int in_h, const std::vector<char>& data, int out_w, int out_h) {
assert(false);
return std::vector<char>();
}
} //unnamed namespace
std::vector<std::vector<char>> icon_fetch (const ConstBlock& block) {
const int32_t h = 16, w = 16;
std::vector<std::vector<char>> icon_fetch (const ConstBlock& block, int width, int height) {
const auto slot_begin = block.cbegin();
const auto slot_end = block.cend();
const std::vector<uint8_t>& palette = block.palette();
assert(palette.size() == 16 * 4);
const int32_t palette_padded_size = ((palette.size() * CHAR_BIT + 31) bitand ~31) / CHAR_BIT;
assert(palette.size() == palette_padded_size);
const int32_t palette_padded_size = 0; //((palette.size() * CHAR_BIT + 31) bitand ~31) / CHAR_BIT;
//assert(palette.size() == palette_padded_size);
const int32_t bpp = 4;
const int32_t scanline_size = ((w * bpp + 31) bitand ~31) / CHAR_BIT;
const int32_t bpp = 24;
const int32_t scanline_size = ((width * bpp + 31) bitand ~31) / CHAR_BIT;
const std::size_t data_offset = sizeof(bmp::g_signature) + sizeof(bmp::FileHeader) + sizeof(bmp::ImageHeader) + palette_padded_size;
const std::size_t bmp_byte_size = data_offset + scanline_size * h;
const std::size_t bmp_byte_size = data_offset + scanline_size * height;
bmp::FileHeader fhead;
bmp::ImageHeader ihead;
fhead.bfSize = static_cast<uint32_t>(bmp_byte_size);
fhead.bfOffBits = static_cast<uint32_t>(data_offset);
ihead.biWidth = h;
ihead.biHeight = w;
bmp::ImageHeader ihead;
ihead.biWidth = width;
ihead.biHeight = height;
ihead.biBitCount = static_cast<uint32_t>(bpp);
ihead.biClrUsed = static_cast<uint32_t>(palette.size() / 4);
ihead.biClrUsed = 0; //static_cast<uint32_t>(palette.size() / 4);
ihead.biClrImportant = ihead.biClrUsed;
ihead.biSizeImage = scanline_size * h;
ihead.biSizeImage = scanline_size * height;
std::vector<std::vector<char>> retval(3);
int32_t icon_num = 0;
std::vector<char> orig_rgb;
for (auto& frame : retval) {
frame.reserve(bmp_byte_size);
std::copy(reinterpret_cast<const char*>(&bmp::g_signature), reinterpret_cast<const char*>(&bmp::g_signature + 1), std::back_inserter(frame));
std::copy(reinterpret_cast<char*>(&fhead), reinterpret_cast<char*>(&fhead + 1), std::back_inserter(frame));
std::copy(reinterpret_cast<char*>(&ihead), reinterpret_cast<char*>(&ihead + 1), std::back_inserter(frame));
std::copy(palette.begin(), palette.end(), std::back_inserter(frame));
assert(palette_padded_size >= palette.size());
std::fill_n(std::back_inserter(frame), palette_padded_size - palette.size(), 0);
//std::copy(palette.begin(), palette.end(), std::back_inserter(frame));
//assert(palette_padded_size >= palette.size());
//std::fill_n(std::back_inserter(frame), palette_padded_size - palette.size(), 0);
const int h = 16, w = 16;
const int in_scanline_size = ((w * 24 + 31) bitand ~31) / CHAR_BIT;
orig_rgb.resize(in_scanline_size * h);
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w / 2; ++x) {
const uint8_t curr = *(slot_begin + 128 + (w / 2 * y) + 128 * icon_num + x);
const int dst_index_a = y * in_scanline_size + x * 2 * 3;
const int dst_index_b = dst_index_a + 3;
const int src_index_a = (curr bitand 0x0f) * 4;
const int src_index_b = ((curr bitand 0xf0) >> 4) * 4;
orig_rgb[dst_index_a + 0] = palette[src_index_a + 0];
orig_rgb[dst_index_a + 1] = palette[src_index_a + 1];
orig_rgb[dst_index_a + 2] = palette[src_index_a + 2];
orig_rgb[dst_index_b + 0] = palette[src_index_b + 0];
orig_rgb[dst_index_b + 1] = palette[src_index_b + 1];
orig_rgb[dst_index_b + 2] = palette[src_index_b + 2];
}
}
std::vector<char> resized_rgb;
if (w != width or h != height) {
srgb_to_linear(orig_rgb, w, h);
resized_rgb = bilinear_resize(w, h, orig_rgb, width, height);
linear_to_srgb(resized_rgb, width, height);
}
else {
std::swap(resized_rgb, orig_rgb);
assert(in_scanline_size == scanline_size);
}
assert(frame.size() == data_offset);
frame.resize(data_offset + scanline_size * h);
frame.resize(data_offset + scanline_size * height);
for (int32_t y = 0; y < h; ++y) {
for (int32_t x = 0; x < w / 2; ++x) {
const uint8_t curr = *(slot_begin + 128 + (w / 2 * y) + 128 * icon_num + x);
frame[data_offset + (h - 1 - y) * scanline_size + x] =
static_cast<char>(((curr & 0x0f) << 4) | ((curr & 0xf0) >> 4));
}
//std::copy_n(slot_begin + 128 + h / 2 * y, scanline_size, frame.begin() + data_offset + (h - 1 - y) * scanline_size);
std::copy_n(
resized_rgb.begin() + scanline_size * (h - 1 - y),
scanline_size,
frame.begin() + data_offset + y * scanline_size
);
}
}
return retval;

View file

@ -3,4 +3,4 @@
#include "block.hpp"
#include <vector>
std::vector<std::vector<char>> icon_fetch (const ConstBlock& block);
std::vector<std::vector<char>> icon_fetch (const ConstBlock& block, int width, int height);

View file

@ -4,18 +4,24 @@
#include <iostream>
#include <fstream>
#include "nana/gui/animation.hpp"
#include <vector>
#include <iostream>
int main() {
nana::form frm;
const MemoryCard mc(std::ifstream("/home/michele/dev/code/cpp/memoserv/michele_epsxe000.mcr", std::ios::binary));
grid grid1{frm, 16, &mc};
grid grid2{frm, 16, &mc};
#if !defined(NDEBUG)
grid1.bgcolor(nana::colors::azure);
//grid1.bgcolor(nana::colors::azure);
#endif
std::cout << "Hello world\n";
frm.div("vert<>< <weight=5%><grid1><weight=5%><> ><>");
frm.div("vert<>< <weight=5%><grid1><weight=5%><grid2> ><>");
frm["grid1"] << grid1;
frm["grid2"] << grid2;
frm.collocate();
frm.show();