diff options
Diffstat (limited to 'src/ppu.c')
-rw-r--r-- | src/ppu.c | 46 |
1 files changed, 32 insertions, 14 deletions
@@ -25,6 +25,8 @@ | |||
25 | static size_t screen_width = 0; | 25 | static size_t screen_width = 0; |
26 | static size_t screen_height = 0; | 26 | static size_t screen_height = 0; |
27 | static size_t bpp = 0; | 27 | static size_t bpp = 0; |
28 | static int fb_file = 0; | ||
29 | static int refresh_file = 0; | ||
28 | 30 | ||
29 | static u8 *framebuffer = 0; | 31 | static u8 *framebuffer = 0; |
30 | 32 | ||
@@ -45,10 +47,13 @@ static u8 blending[5][16] = { | |||
45 | 47 | ||
46 | u16 | 48 | u16 |
47 | rgb565(u32 rgba) { | 49 | rgb565(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 | ||
54 | void | 59 | void |
@@ -142,13 +147,20 @@ set_tty(bool graphics) { | |||
142 | int | 147 | int |
143 | ppu_init(void) { | 148 | ppu_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; |