aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-09-08 14:52:24 +0200
committerBad Diode <bd@badd10de.dev>2021-09-08 14:52:24 +0200
commite98ffd3a32cff5d367d360be9ebe2d1e1a416054 (patch)
tree6159609637ab5c532df66762c4167c09c4192004
parent7654bb013814d7cf317f7dfd69238abe6dc30ef1 (diff)
downloaduxnrpi-e98ffd3a32cff5d367d360be9ebe2d1e1a416054.tar.gz
uxnrpi-e98ffd3a32cff5d367d360be9ebe2d1e1a416054.zip
Add dirty lines and redraw optimization to ppu
-rw-r--r--src/main.c12
-rw-r--r--src/ppu.c40
2 files changed, 42 insertions, 10 deletions
diff --git a/src/main.c b/src/main.c
index fc073c9..e2b39b8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -44,6 +44,10 @@ docolors(Device *d) {
44 for(size_t i = 4; i < 16; ++i) { 44 for(size_t i = 4; i < 16; ++i) {
45 palette[i] = palette[i / 4]; 45 palette[i] = palette[i / 4];
46 } 46 }
47
48 // Redraw the screen if we change the color palette.
49 reqdraw = 1;
50 redraw_screen();
47} 51}
48 52
49void 53void
@@ -74,6 +78,7 @@ screen_talk(Device *d, u8 b0, u8 w) {
74 Uint16 y = mempeek16(d->dat, 0xa); 78 Uint16 y = mempeek16(d->dat, 0xa);
75 Uint8 layer = d->dat[0xe] >> 4 & 0x1; 79 Uint8 layer = d->dat[0xe] >> 4 & 0x1;
76 ppu_pixel(&ppu, layer, x, y, d->dat[0xe] & 0x3); 80 ppu_pixel(&ppu, layer, x, y, d->dat[0xe] & 0x3);
81 reqdraw = 1;
77 } else if(w && b0 == 0xf) { 82 } else if(w && b0 == 0xf) {
78 Uint16 x = mempeek16(d->dat, 0x8); 83 Uint16 x = mempeek16(d->dat, 0x8);
79 Uint16 y = mempeek16(d->dat, 0xa); 84 Uint16 y = mempeek16(d->dat, 0xa);
@@ -83,6 +88,7 @@ screen_talk(Device *d, u8 b0, u8 w) {
83 ppu_2bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1); 88 ppu_2bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1);
84 else 89 else
85 ppu_1bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1); 90 ppu_1bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1);
91 reqdraw = 1;
86 } 92 }
87} 93}
88 94
@@ -153,10 +159,6 @@ void main(void) {
153 uxn_eval(&u, mempeek16(devscreen->dat, 0)); 159 uxn_eval(&u, mempeek16(devscreen->dat, 0));
154 160
155 // Blit ppu.pixels to the framebuffer. 161 // Blit ppu.pixels to the framebuffer.
156 // NOTE: This is very inefficient, we likely want to keep track of the 162 blit_framebuffer(&ppu);
157 // lines/tiles that have changed and only copy those.
158 for (size_t i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) {
159 framebuffer[i] = palette[ppu.pixels[i]];
160 }
161 } 163 }
162} 164}
diff --git a/src/ppu.c b/src/ppu.c
index aeb3699..85245b2 100644
--- a/src/ppu.c
+++ b/src/ppu.c
@@ -15,13 +15,15 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15WITH REGARD TO THIS SOFTWARE. 15WITH REGARD TO THIS SOFTWARE.
16*/ 16*/
17 17
18#define SCREEN_WIDTH 64 * 8 / 2 18#define SCREEN_WIDTH 64 * 8
19#define SCREEN_HEIGHT 40 * 8 / 2 19#define SCREEN_HEIGHT 40 * 8
20 20
21static u32 *framebuffer = 0; 21static u32 *framebuffer = 0;
22 22
23static u32 palette[16]; 23static u32 palette[16] = {0};
24static u8 pixels_buf[SCREEN_WIDTH * SCREEN_HEIGHT]; 24static u8 pixels_buf[SCREEN_WIDTH * SCREEN_HEIGHT] = {0};
25static u8 dirty_lines[SCREEN_HEIGHT] = {0};
26static u8 reqdraw = 0;
25 27
26static Uint8 blending[5][16] = { 28static Uint8 blending[5][16] = {
27 {0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0}, 29 {0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0},
@@ -37,8 +39,8 @@ ppu_pixel(Ppu *p, Uint8 layer, Uint16 x, Uint16 y, Uint8 color)
37 Uint8 *pixel = &p->pixels[idx], shift = layer * 2; 39 Uint8 *pixel = &p->pixels[idx], shift = layer * 2;
38 if(x < p->width && y < p->height) { 40 if(x < p->width && y < p->height) {
39 *pixel = (*pixel & ~(0x3 << shift)) | (color << shift); 41 *pixel = (*pixel & ~(0x3 << shift)) | (color << shift);
40 // framebuffer[idx] = palette[*pixel];
41 } 42 }
43 dirty_lines[y] |= 1;
42} 44}
43 45
44void 46void
@@ -75,6 +77,13 @@ ppu_2bpp(Ppu *p, Uint8 layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Ui
75 } 77 }
76} 78}
77 79
80void
81redraw_screen(void) {
82 for (size_t j = 0; j < SCREEN_HEIGHT; j++) {
83 dirty_lines[j] |= 1;
84 }
85}
86
78int 87int
79ppu_init(Ppu *p, Uint8 hor, Uint8 ver) { 88ppu_init(Ppu *p, Uint8 hor, Uint8 ver) {
80 p->width = 8 * hor; 89 p->width = 8 * hor;
@@ -135,5 +144,26 @@ ppu_init(Ppu *p, Uint8 hor, Uint8 ver) {
135 palette[2] = 0x007777ff; 144 palette[2] = 0x007777ff;
136 palette[3] = 0x00ff7777; 145 palette[3] = 0x00ff7777;
137 146
147 // Make sure we perform an initial screen drawing.
148 reqdraw = 1;
149 redraw_screen();
150
138 return 1; 151 return 1;
139} 152}
153
154void
155blit_framebuffer(Ppu *p) {
156 if (reqdraw == 0) {
157 return;
158 }
159 for (size_t j = 0; j < SCREEN_HEIGHT; j++) {
160 if (dirty_lines[j] == 1) {
161 for (size_t i = 0; i < SCREEN_WIDTH; i++) {
162 size_t idx = i + j * SCREEN_WIDTH;
163 framebuffer[idx] = palette[p->pixels[idx]];
164 }
165 }
166 dirty_lines[j] = 0;
167 }
168 reqdraw = 0;
169}