aboutsummaryrefslogtreecommitdiffstats
path: root/src/ppu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ppu.c')
-rw-r--r--src/ppu.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/src/ppu.c b/src/ppu.c
index 175b2a7..3afa533 100644
--- a/src/ppu.c
+++ b/src/ppu.c
@@ -25,6 +25,8 @@
25static size_t screen_width = 0; 25static size_t screen_width = 0;
26static size_t screen_height = 0; 26static size_t screen_height = 0;
27static size_t bpp = 0; 27static size_t bpp = 0;
28static int fb_file = 0;
29static int refresh_file = 0;
28 30
29static u8 *framebuffer = 0; 31static u8 *framebuffer = 0;
30 32
@@ -45,10 +47,13 @@ static u8 blending[5][16] = {
45 47
46u16 48u16
47rgb565(u32 rgba) { 49rgb565(u32 rgba) {
48 u16 r = rgba >> 16 & 0xFF; 50 u16 r = (rgba >> 16 & 0xFF);
49 u16 g = rgba >> 8 & 0xFF; 51 u16 g = (rgba >> 8 & 0xFF);
50 u16 b = rgba >> 0 & 0xFF; 52 u16 b = (rgba >> 0 & 0xFF);
51 return (r << 8) | (g << 3) | (b >> 3); 53 r = r >> 3;
54 g = g >> 2;
55 b = b >> 3;
56 return (r << 11) | (g << 5) | b;
52} 57}
53 58
54void 59void
@@ -142,13 +147,20 @@ set_tty(bool graphics) {
142int 147int
143ppu_init(void) { 148ppu_init(void) {
144 // Open frambuffer and get the size. 149 // Open frambuffer and get the size.
145 int fb = open("/dev/graphics/fb0", O_RDWR); 150 fb_file = open("/dev/graphics/fb0", O_RDWR);
146 if (fb <= 0) { 151 if (fb_file <= 0) {
147 fprintf(stderr, "error: couldn't open the framebuffer\n"); 152 fprintf(stderr, "error: couldn't open the framebuffer\n");
148 exit(EXIT_FAILURE); 153 exit(EXIT_FAILURE);
149 } 154 }
155
156 refresh_file = open("/sys/class/graphics/fb0/epd_refresh", O_RDWR);
157 if (refresh_file == 0) {
158 fprintf(stderr, "error: couldn't open the refresh file\n");
159 exit(EXIT_FAILURE);
160 }
161
150 struct fb_var_screeninfo info; 162 struct fb_var_screeninfo info;
151 if (ioctl(fb, FBIOGET_VSCREENINFO, &info) != 0) { 163 if (ioctl(fb_file, FBIOGET_VSCREENINFO, &info) != 0) {
152 fprintf(stderr, "error: couldn't get the framebuffer size\n"); 164 fprintf(stderr, "error: couldn't get the framebuffer size\n");
153 exit(EXIT_FAILURE); 165 exit(EXIT_FAILURE);
154 } 166 }
@@ -156,9 +168,9 @@ ppu_init(void) {
156 // Mmap the framebuffer to a buffer object. 168 // Mmap the framebuffer to a buffer object.
157 screen_width = info.xres; 169 screen_width = info.xres;
158 screen_height = info.yres; 170 screen_height = info.yres;
159 bpp = info.bits_per_pixel / 8; 171 bpp = info.bits_per_pixel;
160 size_t len = bpp * screen_width * screen_height; 172 size_t len = bpp / 8 * screen_width * screen_height;
161 framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0); 173 framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb_file, 0);
162 if (framebuffer == MAP_FAILED) { 174 if (framebuffer == MAP_FAILED) {
163 fprintf(stderr, "error: couldn't mmap the framebuffer\n"); 175 fprintf(stderr, "error: couldn't mmap the framebuffer\n");
164 exit(EXIT_FAILURE); 176 exit(EXIT_FAILURE);
@@ -208,10 +220,16 @@ blit_framebuffer(void) {
208 if (dirty_lines[j] != 0) { 220 if (dirty_lines[j] != 0) {
209 for (size_t i = 0; i < screen_width; i++) { 221 for (size_t i = 0; i < screen_width; i++) {
210 size_t idx = i + j * screen_width; 222 size_t idx = i + j * screen_width;
211 u16 *p = framebuffer; 223 if (bpp == 16) {
212 p[idx] = rgb565(palette[pixels_fg[idx] << 2 | pixels_bg[idx]]); 224 u16 *p = framebuffer;
213 // FIXME: can we generalize this to use bpp instead of having 225 p[idx] = rgb565(palette[pixels_fg[idx] << 2 | pixels_bg[idx]]);
214 // a version for 32/16 bit color? 226 } else if (bpp == 32) {
227 u32 *p = framebuffer;
228 p[idx] = palette[pixels_fg[idx] << 2 | pixels_bg[idx]];
229 } else {
230 fprintf(stderr, "error: wrong bits per pixel (expected 16 or 32)\n");
231 exit(EXIT_FAILURE);
232 }
215 } 233 }
216 } 234 }
217 dirty_lines[j] = 0; 235 dirty_lines[j] = 0;