lsnes rr0-β2
[lsnes.git] / framebuffer.cpp
blob8cd8d03e77227ecee6130f1fbf37feab2f0a3343
1 #include "framebuffer.hpp"
2 #include "lua.hpp"
3 #include "command.hpp"
4 #include "window.hpp"
5 #include "misc.hpp"
6 #include "render.hpp"
8 lcscreen framebuffer;
9 lcscreen screen_nosignal;
10 lcscreen screen_corrupt;
11 extern uint32_t fontdata[];
13 namespace
15 struct render_list_entry
17 uint32_t codepoint;
18 uint32_t x;
19 uint32_t y;
20 uint32_t scale;
23 struct render_list_entry rl_nosignal[] = {
24 {'N', 4, 168, 7},
25 {'O', 60, 168, 7},
26 {'S', 172, 168, 7},
27 {'I', 228, 168, 7},
28 {'G', 284, 168, 7},
29 {'N', 340, 168, 7},
30 {'A', 396, 168, 7},
31 {'L', 452, 168, 7},
32 {0, 0, 0, 0}
35 struct render_list_entry rl_corrupt[] = {
36 {'S', 88, 56, 7},
37 {'Y', 144, 56, 7},
38 {'S', 200, 56, 7},
39 {'T', 256, 56, 7},
40 {'E', 312, 56, 7},
41 {'M', 368, 56, 7},
42 {'S', 116, 168, 7},
43 {'T', 172, 168, 7},
44 {'A', 224, 168, 7},
45 {'T', 280, 168, 7},
46 {'E', 336, 168, 7},
47 {'C', 60, 280, 7},
48 {'O', 116, 280, 7},
49 {'R', 172, 280, 7},
50 {'R', 228, 280, 7},
51 {'U', 284, 280, 7},
52 {'P', 340, 280, 7},
53 {'T', 396, 280, 7},
54 {0, 0, 0, 0}
57 void draw_special_screen(uint16_t* target, struct render_list_entry* rlist)
59 while(rlist->scale) {
60 int32_t x;
61 int32_t y;
62 auto g = find_glyph(rlist->codepoint, 0, 0, 0, x, y);
63 for(uint32_t j = 0; j < 16; j++) {
64 for(uint32_t i = 0; i < 8; i++) {
65 uint32_t slice = g.second + j / 4;
66 uint32_t bit = 31 - ((j % 4) * 8 + i);
67 uint32_t value = (fontdata[slice] >> bit) & 1;
68 if(value) {
69 uint32_t basex = rlist->x + rlist->scale * i;
70 uint32_t basey = rlist->y + rlist->scale * j;
71 for(uint32_t j2 = 0; j2 < rlist->scale; j2++)
72 for(uint32_t i2 = 0; i2 < rlist->scale; i2++)
73 target[(basey + j2) * 512 + (basex + i2)] = 0x7FFF;
77 rlist++;
81 void draw_nosignal(uint16_t* target)
83 for(unsigned i = 0; i < 512 * 448; i++)
84 target[i] = 0x1F;
85 draw_special_screen(target, rl_nosignal);
88 void draw_corrupt(uint16_t* target)
90 for(unsigned i = 0; i < 512 * 448; i++)
91 target[i] = 0x1F;
92 draw_special_screen(target, rl_corrupt);
95 function_ptr_command<arg_filename> take_screenshot("take-screenshot", "Takes a screenshot",
96 "Syntax: take-screenshot <file>\nSaves screenshot to PNG file <file>\n",
97 [](arg_filename file) throw(std::bad_alloc, std::runtime_error) {
98 framebuffer.save_png(file);
99 messages << "Saved PNG screenshot" << std::endl;
103 screen main_screen;
106 void init_special_screens() throw(std::bad_alloc)
108 uint16_t buf[512*448];
109 draw_nosignal(buf);
110 screen_nosignal = lcscreen(buf, 512, 448);
111 draw_corrupt(buf);
112 screen_corrupt = lcscreen(buf, 512, 448);
115 void redraw_framebuffer()
117 uint32_t hscl = 1, vscl = 1;
118 if(framebuffer.width < 512)
119 hscl = 2;
120 if(framebuffer.height < 400)
121 vscl = 2;
122 render_queue rq;
123 struct lua_render_context lrc;
124 lrc.left_gap = 0;
125 lrc.right_gap = 0;
126 lrc.bottom_gap = 0;
127 lrc.top_gap = 0;
128 lrc.queue = &rq;
129 lrc.width = framebuffer.width * hscl;
130 lrc.height = framebuffer.height * vscl;
131 lrc.rshift = main_screen.active_rshift;
132 lrc.gshift = main_screen.active_gshift;
133 lrc.bshift = main_screen.active_bshift;
134 lua_callback_do_paint(&lrc);
135 main_screen.reallocate(framebuffer.width * hscl + lrc.left_gap + lrc.right_gap, framebuffer.height * vscl +
136 lrc.top_gap + lrc.bottom_gap, lrc.left_gap, lrc.top_gap);
137 main_screen.copy_from(framebuffer, hscl, vscl);
138 //We would want divide by 2, but we'll do it ourselves in order to do mouse.
139 window::set_window_compensation(lrc.left_gap, lrc.top_gap, 1, 1);
140 rq.run(main_screen);
141 window::notify_screen_update();