lsnes rr2-β24
[lsnes.git] / src / lua / halo.cpp
blobcd02e1c206ebef1d374b0e37a13040ec27102f23
1 #include "lua/halo.hpp"
2 #include "lua/bitmap.hpp"
3 #include "library/range.hpp"
4 #include "library/eatarg.hpp"
5 #include <cstdint>
6 #include <iostream>
8 namespace
10 void render_halo1(unsigned char* prow, size_t width)
12 uint32_t x = prow[0];
13 for(unsigned i = 0; i < width - 1; i++) {
14 x = (x << 10) | prow[i + 1];
15 prow[i] = (x >> 19) | (x >> 10) | (x << 1);
17 prow[width - 1] = (x >> 10) | (x << 1);
19 void render_halo2(unsigned char* prow, const unsigned char* srow, size_t width)
21 uint32_t x = prow[0];
22 uint32_t y = srow[0];
23 uint32_t z = 0;
24 for(unsigned i = 0; i < width - 1; i++) {
25 x = (x << 10) | prow[i + 1];
26 y = (y << 10) | srow[i + 1];
27 z = x | y;
28 prow[i] = (z >> 19) | (x >> 10) | (z << 1) | (y >> 9);
30 prow[width - 1] = (x >> 10) | ((x | y) << 1) | (y >> 9);
32 void render_halo3(unsigned char* prow, const unsigned char* arow, const unsigned char* brow, size_t width)
34 uint32_t x = prow[0];
35 uint32_t y = arow[0] | brow[0];
36 uint32_t z = 0;
37 for(unsigned i = 0; i < width - 1; i++) {
38 x = (x << 10) | prow[i + 1];
39 y = (y << 10) | arow[i + 1] | brow[i + 1];
40 z = x | y;
41 prow[i] = (z >> 19) | (x >> 10) | (z << 1) | (y >> 9);
43 prow[width - 1] = (x >> 10) | (z << 1) | (y >> 9);
45 void mask_halo(unsigned char* pixmap, size_t pixels)
47 for(size_t i = 0; i < pixels; i++)
48 pixmap[i] &= 0x03;
51 template<bool T> class text_bitmap_holder
53 public:
54 text_bitmap_holder(const framebuffer::color& bg, const framebuffer::color& fg,
55 const framebuffer::color& hl, const unsigned char* _pixmap, size_t _width)
57 cmap[0] = bg;
58 cmap[1] = fg;
59 cmap[2] = hl;
60 cmap[3] = fg;
61 pixmap = _pixmap;
62 width = _width;
64 size_t stride() { return width; }
65 void lock() {}
66 void unlock() {}
67 void draw(size_t bmpidx, typename framebuffer::fb<T>::element_t& target)
69 cmap[pixmap[bmpidx]].apply(target);
71 private:
72 framebuffer::color cmap[4];
73 const unsigned char* pixmap;
74 size_t width;
78 void render_halo(unsigned char* pixmap, size_t width, size_t height)
80 if(!height || !width) return;
81 if(height == 1) {
82 render_halo1(pixmap, width);
83 } else {
84 render_halo2(pixmap, pixmap + width, width);
85 size_t off = width;
86 for(size_t i = 1; i < height - 1; i++, off += width)
87 render_halo3(pixmap + off, pixmap + off - width, pixmap + off + width, width);
88 render_halo2(pixmap + off, pixmap + off - width, width);
90 mask_halo(pixmap, width * height);
93 template<bool X> void halo_blit(struct framebuffer::fb<X>& scr, unsigned char* pixmap, size_t width,
94 size_t height, size_t owidth, size_t oheight, uint32_t x, uint32_t y, framebuffer::color& bg,
95 framebuffer::color& fg, framebuffer::color& hl) throw()
97 uint32_t low = 1;
98 uint32_t border = 0;
99 if(hl) {
100 //Make space for halo.
101 low = 0;
102 border = 2;
103 render_halo(pixmap, width, height);
105 range bX = (range::make_w(scr.get_width()) - x) & range::make_s(low, owidth + border);
106 range bY = (range::make_w(scr.get_height()) - y) & range::make_s(low, oheight + border);
107 //Because outside is always false, screen can be passed as 0x0.
108 lua_bitmap_composite(scr, x, y, bX, bY, range::make_w(0), range::make_w(0), false,
109 text_bitmap_holder<X>(bg, fg, hl, pixmap, width));
112 void _pull_fn_68269328963289632986296386936()
114 eat_argument(halo_blit<false>);
115 eat_argument(halo_blit<true>);