Fix race between killing object and drawing object
[lsnes.git] / src / interface / cover.cpp
blob845ee189bc1b3f324af1ae9da5b73f511da85bd1
1 #include "core/instance.hpp"
2 #include "core/moviedata.hpp"
3 #include "core/memorymanip.hpp"
4 #include "core/rom.hpp"
5 #include "interface/cover.hpp"
6 #include "library/minmax.hpp"
7 #include "library/utf8.hpp"
8 #include "fonts/wrapper.hpp"
9 #include <iostream>
11 namespace
13 template<size_t pstride>
14 void cover_render_character(void* fb, unsigned x, unsigned y, uint32_t ch, uint32_t fg, uint32_t bg,
15 size_t w, size_t h, size_t istride)
17 unsigned char* _fg = reinterpret_cast<unsigned char*>(&fg);
18 unsigned char* _bg = reinterpret_cast<unsigned char*>(&bg);
19 if(x >= w || y >= h)
20 return;
21 const framebuffer::font::glyph& g = main_font.get_glyph(ch);
22 unsigned maxw = min((size_t)(g.wide ? 16 : 8), (size_t)(w - x));
23 unsigned maxh = min((size_t)16, (size_t)(h - y));
24 unsigned char* cellbase = reinterpret_cast<unsigned char*>(fb) + y * istride + pstride * x;
25 if(g.wide) {
26 //Wide character.
27 for(size_t y2 = 0; y2 < maxh; y2++) {
28 uint32_t d = g.data[y2 >> 1];
29 d >>= 16 - ((y2 & 1) << 4);
30 for(size_t j = 0; j < maxw; j++) {
31 uint32_t b = 15 - j;
32 if(((d >> b) & 1) != 0) {
33 for(unsigned k = 0; k < pstride; k++)
34 cellbase[pstride * j + k] = _fg[k];
35 } else {
36 for(unsigned k = 0; k < pstride; k++)
37 cellbase[pstride * j + k] = _bg[k];
40 cellbase += istride;
42 } else {
43 //Narrow character.
44 for(size_t y2 = 0; y2 < maxh; y2++) {
45 uint32_t d = g.data[y2 >> 2];
46 d >>= 24 - ((y2 & 3) << 3);
47 for(size_t j = 0; j < maxw; j++) {
48 uint32_t b = 7 - j;
49 if(((d >> b) & 1) != 0) {
50 for(unsigned k = 0; k < pstride; k++)
51 cellbase[pstride * j + k] = _fg[k];
52 } else {
53 for(unsigned k = 0; k < pstride; k++)
54 cellbase[pstride * j + k] = _bg[k];
57 cellbase += istride;
63 void cover_render_character(void* fb, unsigned x, unsigned y, uint32_t ch, uint32_t fg, uint32_t bg, size_t w,
64 size_t h, size_t istride, size_t pstride)
66 if(pstride == 2)
67 cover_render_character<2>(fb, x, y, ch, fg, bg, w, h, istride);
68 if(pstride == 3)
69 cover_render_character<3>(fb, x, y, ch, fg, bg, w, h, istride);
70 if(pstride == 4)
71 cover_render_character<4>(fb, x, y, ch, fg, bg, w, h, istride);
74 void cover_render_string(void* fb, unsigned x, unsigned y, const std::string& str, uint32_t fg, uint32_t bg,
75 size_t w, size_t h, size_t istride, size_t pstride)
77 utf8::to32i(str.begin(), str.end(), lambda_output_iterator<int32_t>([fb, &x, &y, fg, bg, w, h, istride,
78 pstride](int32_t u) {
79 if(u != 9 && u != 10)
80 cover_render_character(fb, x, y, u, fg, bg, w, h, istride, pstride);
81 cover_next_position(u, x, y);
82 }));
85 void cover_next_position(uint32_t ch, unsigned& x, unsigned& y)
87 if(ch == 9)
88 x = (x + 63) >> 6 << 6;
89 else if(ch == 10) {
90 x = 0;
91 y = y + 16;
92 } else {
93 const framebuffer::font::glyph& g = main_font.get_glyph(ch);
94 x = x + (g.wide ? 16 : 8);
98 void cover_next_position(const std::string& str, unsigned& x, unsigned& y)
100 utf8::to32i(str.begin(), str.end(), lambda_output_iterator<int32_t>([&x, &y](int32_t u) {
101 cover_next_position(u, x, y);
102 }));
105 std::vector<std::string> cover_information()
107 auto& core = CORE();
108 std::vector<std::string> ret;
109 ret.push_back("System: " + core.rom->get_hname() + " (" + core.rom->region_get_hname() + ")");
110 return ret;