aboutsummaryrefslogtreecommitdiffstats
path: root/src/ppu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ppu.c')
-rw-r--r--src/ppu.c82
1 files changed, 50 insertions, 32 deletions
diff --git a/src/ppu.c b/src/ppu.c
index aa99ed8..175b2a7 100644
--- a/src/ppu.c
+++ b/src/ppu.c
@@ -4,7 +4,7 @@
4 4
5#include <linux/fb.h> 5#include <linux/fb.h>
6#include <sys/ioctl.h> 6#include <sys/ioctl.h>
7#include <sys/kd.h> 7// #include <sys/kd.h>
8#include <sys/mman.h> 8#include <sys/mman.h>
9 9
10#include "ppu.h" 10#include "ppu.h"
@@ -24,8 +24,9 @@
24 24
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;
27 28
28static u32 *framebuffer = 0; 29static u8 *framebuffer = 0;
29 30
30static u32 palette[16]; 31static u32 palette[16];
31static u8 *pixels_fg; 32static u8 *pixels_fg;
@@ -42,6 +43,14 @@ static u8 blending[5][16] = {
42 {2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2}, 43 {2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2},
43 {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}}; 44 {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}};
44 45
46u16
47rgb565(u32 rgba) {
48 u16 r = rgba >> 16 & 0xFF;
49 u16 g = rgba >> 8 & 0xFF;
50 u16 b = rgba >> 0 & 0xFF;
51 return (r << 8) | (g << 3) | (b >> 3);
52}
53
45void 54void
46ppu_pixel(u8 *layer, u16 x, u16 y, u8 color) { 55ppu_pixel(u8 *layer, u16 x, u16 y, u8 color) {
47 if(x < screen_width && y < screen_height) { 56 if(x < screen_width && y < screen_height) {
@@ -101,39 +110,39 @@ set_tty(bool graphics) {
101 exit(EXIT_FAILURE); 110 exit(EXIT_FAILURE);
102 } 111 }
103 112
104 if (graphics) { 113 // if (graphics) {
105 if (ioctl(tty, KDSETMODE, KD_GRAPHICS)) { 114 // if (ioctl(tty, KDSETMODE, KD_GRAPHICS)) {
106 fprintf(stderr,"error: setting graphics mode failed\n"); 115 // fprintf(stderr,"error: setting graphics mode failed\n");
107 exit(EXIT_FAILURE); 116 // exit(EXIT_FAILURE);
108 } 117 // }
109 struct termios t; 118 // struct termios t;
110 if (tcgetattr(STDIN_FILENO, &t)) { 119 // if (tcgetattr(STDIN_FILENO, &t)) {
111 fprintf(stderr, "error: couldn't disable terminal echo\n"); 120 // fprintf(stderr, "error: couldn't disable terminal echo\n");
112 exit(EXIT_FAILURE); 121 // exit(EXIT_FAILURE);
113 } 122 // }
114 prev_t = t; 123 // prev_t = t;
115 t.c_lflag &= ~((tcflag_t) ECHO); 124 // t.c_lflag &= ~((tcflag_t) ECHO);
116 if (tcsetattr(STDIN_FILENO, TCSANOW, &t)) { 125 // if (tcsetattr(STDIN_FILENO, TCSANOW, &t)) {
117 fprintf(stderr, "error: couldn't disable terminal echo\n"); 126 // fprintf(stderr, "error: couldn't disable terminal echo\n");
118 exit(EXIT_FAILURE); 127 // exit(EXIT_FAILURE);
119 } 128 // }
120 } else { 129 // } else {
121 if (ioctl(tty, KDSETMODE, KD_TEXT)) { 130 // if (ioctl(tty, KDSETMODE, KD_TEXT)) {
122 fprintf(stderr,"error: setting text mode failed\n"); 131 // fprintf(stderr,"error: setting text mode failed\n");
123 exit(EXIT_FAILURE); 132 // exit(EXIT_FAILURE);
124 } 133 // }
125 if (tcsetattr(STDIN_FILENO, TCSANOW, &prev_t)) { 134 // if (tcsetattr(STDIN_FILENO, TCSANOW, &prev_t)) {
126 fprintf(stderr, "error: couldn't restore terminal attributes\n"); 135 // fprintf(stderr, "error: couldn't restore terminal attributes\n");
127 exit(EXIT_FAILURE); 136 // exit(EXIT_FAILURE);
128 } 137 // }
129 } 138 // }
130 close(tty); 139 close(tty);
131} 140}
132 141
133int 142int
134ppu_init(void) { 143ppu_init(void) {
135 // Open frambuffer and get the size. 144 // Open frambuffer and get the size.
136 int fb = open("/dev/fb0", O_RDWR); 145 int fb = open("/dev/graphics/fb0", O_RDWR);
137 if (fb <= 0) { 146 if (fb <= 0) {
138 fprintf(stderr, "error: couldn't open the framebuffer\n"); 147 fprintf(stderr, "error: couldn't open the framebuffer\n");
139 exit(EXIT_FAILURE); 148 exit(EXIT_FAILURE);
@@ -147,7 +156,8 @@ ppu_init(void) {
147 // Mmap the framebuffer to a buffer object. 156 // Mmap the framebuffer to a buffer object.
148 screen_width = info.xres; 157 screen_width = info.xres;
149 screen_height = info.yres; 158 screen_height = info.yres;
150 size_t len = 4 * screen_width * screen_height; 159 bpp = info.bits_per_pixel / 8;
160 size_t len = bpp * screen_width * screen_height;
151 framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0); 161 framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
152 if (framebuffer == MAP_FAILED) { 162 if (framebuffer == MAP_FAILED) {
153 fprintf(stderr, "error: couldn't mmap the framebuffer\n"); 163 fprintf(stderr, "error: couldn't mmap the framebuffer\n");
@@ -164,7 +174,7 @@ ppu_init(void) {
164 } 174 }
165 175
166 // Prepare TTY for graphics mode. 176 // Prepare TTY for graphics mode.
167 set_tty(true); 177 // set_tty(true);
168 178
169 // Initialize default palette. 179 // Initialize default palette.
170 palette[0] = 0x444444; 180 palette[0] = 0x444444;
@@ -177,6 +187,9 @@ ppu_init(void) {
177 memset(pixels_bg, 0, screen_width * screen_height); 187 memset(pixels_bg, 0, screen_width * screen_height);
178 memset(dirty_lines, 1, screen_height); 188 memset(dirty_lines, 1, screen_height);
179 189
190 // Clear framebuffer.
191 memset(framebuffer, 0xFF, len);
192
180 // Make sure we perform an initial screen drawing. 193 // Make sure we perform an initial screen drawing.
181 reqdraw = 1; 194 reqdraw = 1;
182 redraw_screen(); 195 redraw_screen();
@@ -189,11 +202,16 @@ blit_framebuffer(void) {
189 if (reqdraw == 0) { 202 if (reqdraw == 0) {
190 return; 203 return;
191 } 204 }
205 // TODO: add some parameter to account for zoom? for example we may want to
206 // have an internal resolution smaller than the screen!
192 for (size_t j = 0; j < screen_height; j++) { 207 for (size_t j = 0; j < screen_height; j++) {
193 if (dirty_lines[j] != 0) { 208 if (dirty_lines[j] != 0) {
194 for (size_t i = 0; i < screen_width; i++) { 209 for (size_t i = 0; i < screen_width; i++) {
195 size_t idx = i + j * screen_width; 210 size_t idx = i + j * screen_width;
196 framebuffer[idx] = palette[pixels_fg[idx] << 2 | pixels_bg[idx]]; 211 u16 *p = framebuffer;
212 p[idx] = rgb565(palette[pixels_fg[idx] << 2 | pixels_bg[idx]]);
213 // FIXME: can we generalize this to use bpp instead of having
214 // a version for 32/16 bit color?
197 } 215 }
198 } 216 }
199 dirty_lines[j] = 0; 217 dirty_lines[j] = 0;