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:
parent
1c8f07d51d
commit
b0530a2be6
7 changed files with 130 additions and 52 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
build
|
build
|
||||||
|
tags
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace {
|
||||||
#endif
|
#endif
|
||||||
const uint8_t alpha = (blue | green | red | black_flag ? 0xFF : 0x00);
|
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(blue);
|
||||||
retval.push_back(green);
|
retval.push_back(green);
|
||||||
retval.push_back(red);
|
retval.push_back(red);
|
||||||
|
|
|
@ -8,33 +8,33 @@ namespace implem {
|
||||||
void draw_icons (
|
void draw_icons (
|
||||||
int icon_size,
|
int icon_size,
|
||||||
const MemoryCard& mc,
|
const MemoryCard& mc,
|
||||||
std::array<nana::animation, 15>& icons,
|
std::vector<nana::animation>& icons,
|
||||||
nana::widget& wid
|
nana::widget& wid
|
||||||
) {
|
) {
|
||||||
assert(icon_size);
|
assert(icon_size);
|
||||||
|
|
||||||
for (int z = 0; z < icons.size(); ++z) {
|
for (int z = 0; z < icons.size(); ++z) {
|
||||||
nana::frameset fset;
|
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;
|
nana::paint::image img;
|
||||||
img.open(frame.data(), frame.size());
|
img.open(frame.data(), frame.size());
|
||||||
fset.push_back(img);
|
fset.push_back(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int x = (16 + 2) * (z % 3);
|
icons[z].push_back(fset);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} //namespace implem
|
} //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 (
|
void grid_drawer_trigger::attached (
|
||||||
nana::widget& widget,
|
nana::widget& widget,
|
||||||
|
@ -43,28 +43,52 @@ void grid_drawer_trigger::attached (
|
||||||
using nana::effects::edge_nimbus;
|
using nana::effects::edge_nimbus;
|
||||||
using nana::API::dev::enable_space_click;
|
using nana::API::dev::enable_space_click;
|
||||||
using nana::API::tabstop;
|
using nana::API::tabstop;
|
||||||
using nana::API::effects_edge_nimbus;
|
|
||||||
using nana::API::dev::set_measurer;
|
|
||||||
|
|
||||||
m_graph = &graph;
|
m_graph = &graph;
|
||||||
m_widget = &widget;
|
m_widget = &widget;
|
||||||
|
|
||||||
nana::window wd = widget;
|
nana::window wd = widget;
|
||||||
|
|
||||||
enable_space_click(widget, true);
|
enable_space_click(widget, true);
|
||||||
tabstop(wd);
|
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) {
|
void grid_drawer_trigger::set_memorycard (const MemoryCard* mc) {
|
||||||
m_memorycard = mc;
|
m_memorycard = mc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void grid_drawer_trigger::_m_draw_background (
|
//void grid_drawer_trigger::_m_draw_background (
|
||||||
nana::paint::graphics&,
|
// nana::paint::graphics&,
|
||||||
bool is_mouse_down
|
// bool is_mouse_down
|
||||||
) {
|
//) {
|
||||||
assert(m_memorycard);
|
// assert(m_memorycard);
|
||||||
implem::draw_icons(16, *m_memorycard, m_icons, *m_widget);
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,16 +22,19 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void attached(nana::widget&, nana::paint::graphics&) override;
|
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_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);
|
//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::widget* m_widget{nullptr};
|
||||||
nana::paint::graphics* m_graph{nullptr};
|
nana::paint::graphics* m_graph{nullptr};
|
||||||
const MemoryCard* m_memorycard{nullptr};
|
const MemoryCard* m_memorycard{nullptr};
|
||||||
bool m_is_ms_down{false};
|
bool m_is_ms_down{false};
|
||||||
|
bool m_icons_added{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename DrawerTrigger>
|
template <typename DrawerTrigger>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
namespace bmp {
|
namespace bmp {
|
||||||
|
@ -28,56 +29,99 @@ namespace {
|
||||||
uint32_t biClrImportant = 0;
|
uint32_t biClrImportant = 0;
|
||||||
};
|
};
|
||||||
} //namespace bmp
|
} //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
|
} //unnamed namespace
|
||||||
|
|
||||||
std::vector<std::vector<char>> icon_fetch (const ConstBlock& block) {
|
std::vector<std::vector<char>> icon_fetch (const ConstBlock& block, int width, int height) {
|
||||||
const int32_t h = 16, w = 16;
|
|
||||||
|
|
||||||
const auto slot_begin = block.cbegin();
|
const auto slot_begin = block.cbegin();
|
||||||
const auto slot_end = block.cend();
|
const auto slot_end = block.cend();
|
||||||
const std::vector<uint8_t>& palette = block.palette();
|
const std::vector<uint8_t>& palette = block.palette();
|
||||||
assert(palette.size() == 16 * 4);
|
assert(palette.size() == 16 * 4);
|
||||||
const int32_t palette_padded_size = ((palette.size() * CHAR_BIT + 31) bitand ~31) / CHAR_BIT;
|
const int32_t palette_padded_size = 0; //((palette.size() * CHAR_BIT + 31) bitand ~31) / CHAR_BIT;
|
||||||
assert(palette.size() == palette_padded_size);
|
//assert(palette.size() == palette_padded_size);
|
||||||
|
|
||||||
const int32_t bpp = 4;
|
const int32_t bpp = 24;
|
||||||
const int32_t scanline_size = ((w * bpp + 31) bitand ~31) / CHAR_BIT;
|
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 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::FileHeader fhead;
|
||||||
bmp::ImageHeader ihead;
|
|
||||||
fhead.bfSize = static_cast<uint32_t>(bmp_byte_size);
|
fhead.bfSize = static_cast<uint32_t>(bmp_byte_size);
|
||||||
fhead.bfOffBits = static_cast<uint32_t>(data_offset);
|
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.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.biClrImportant = ihead.biClrUsed;
|
||||||
ihead.biSizeImage = scanline_size * h;
|
ihead.biSizeImage = scanline_size * height;
|
||||||
|
|
||||||
std::vector<std::vector<char>> retval(3);
|
std::vector<std::vector<char>> retval(3);
|
||||||
int32_t icon_num = 0;
|
int32_t icon_num = 0;
|
||||||
|
std::vector<char> orig_rgb;
|
||||||
for (auto& frame : retval) {
|
for (auto& frame : retval) {
|
||||||
frame.reserve(bmp_byte_size);
|
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<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*>(&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(reinterpret_cast<char*>(&ihead), reinterpret_cast<char*>(&ihead + 1), std::back_inserter(frame));
|
||||||
std::copy(palette.begin(), palette.end(), std::back_inserter(frame));
|
//std::copy(palette.begin(), palette.end(), std::back_inserter(frame));
|
||||||
assert(palette_padded_size >= palette.size());
|
//assert(palette_padded_size >= palette.size());
|
||||||
std::fill_n(std::back_inserter(frame), palette_padded_size - palette.size(), 0);
|
//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);
|
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 y = 0; y < h; ++y) {
|
||||||
for (int32_t x = 0; x < w / 2; ++x) {
|
std::copy_n(
|
||||||
const uint8_t curr = *(slot_begin + 128 + (w / 2 * y) + 128 * icon_num + x);
|
resized_rgb.begin() + scanline_size * (h - 1 - y),
|
||||||
frame[data_offset + (h - 1 - y) * scanline_size + x] =
|
scanline_size,
|
||||||
static_cast<char>(((curr & 0x0f) << 4) | ((curr & 0xf0) >> 4));
|
frame.begin() + data_offset + y * scanline_size
|
||||||
}
|
);
|
||||||
//std::copy_n(slot_begin + 128 + h / 2 * y, scanline_size, frame.begin() + data_offset + (h - 1 - y) * scanline_size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
#include "block.hpp"
|
#include "block.hpp"
|
||||||
#include <vector>
|
#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);
|
||||||
|
|
|
@ -4,18 +4,24 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "nana/gui/animation.hpp"
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
nana::form frm;
|
nana::form frm;
|
||||||
|
|
||||||
const MemoryCard mc(std::ifstream("/home/michele/dev/code/cpp/memoserv/michele_epsxe000.mcr", std::ios::binary));
|
const MemoryCard mc(std::ifstream("/home/michele/dev/code/cpp/memoserv/michele_epsxe000.mcr", std::ios::binary));
|
||||||
grid grid1{frm, 16, &mc};
|
grid grid1{frm, 16, &mc};
|
||||||
|
grid grid2{frm, 16, &mc};
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
grid1.bgcolor(nana::colors::azure);
|
//grid1.bgcolor(nana::colors::azure);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::cout << "Hello world\n";
|
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["grid1"] << grid1;
|
||||||
|
frm["grid2"] << grid2;
|
||||||
frm.collocate();
|
frm.collocate();
|
||||||
frm.show();
|
frm.show();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue