... | ... |
@@ -19,6 +19,14 @@ static Uint8 blending[5][16] = { |
19 | 19 |
{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2}, |
20 | 20 |
{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}}; |
21 | 21 |
|
22 |
+void |
|
23 |
+ppu_frame(Ppu *p) |
|
24 |
+{ |
|
25 |
+ p->redraw = 0; |
|
26 |
+ p->i0 = p->width / PPW + p->height * p->stride; |
|
27 |
+ p->i1 = 0; |
|
28 |
+} |
|
29 |
+ |
|
22 | 30 |
static void |
23 | 31 |
ppu_clear(Ppu *p) |
24 | 32 |
{ |
... | ... |
@@ -27,55 +35,55 @@ ppu_clear(Ppu *p) |
27 | 35 |
p->dat[i] = 0; |
28 | 36 |
} |
29 | 37 |
|
30 |
-unsigned int |
|
38 |
+void |
|
31 | 39 |
ppu_pixel(Ppu *p, int fg, Uint16 x, Uint16 y, Uint8 color) |
32 | 40 |
{ |
33 |
- unsigned int ret, i = x / PPW + y * p->stride, shift = x % PPW * 4; |
|
41 |
+ unsigned int v, i = x / PPW + y * p->stride, shift = x % PPW * 4; |
|
34 | 42 |
if(x >= p->width || y >= p->height) |
35 |
- return 0; |
|
36 |
- ret = p->dat[i]; |
|
43 |
+ return; |
|
44 |
+ v = p->dat[i]; |
|
37 | 45 |
if(fg) shift += 2; |
38 | 46 |
p->dat[i] &= ~(3 << shift); |
39 | 47 |
p->dat[i] |= color << shift; |
40 |
- return ret ^ p->dat[i]; |
|
48 |
+ if((v ^ p->dat[i]) != 0){ |
|
49 |
+ p->redraw = 1; |
|
50 |
+ p->i0 = p->i0 < i ? p->i0 : i; |
|
51 |
+ p->i1 = p->i1 > i ? p->i1 : i; |
|
52 |
+ } |
|
41 | 53 |
} |
42 | 54 |
|
43 |
-unsigned int |
|
55 |
+void |
|
44 | 56 |
ppu_1bpp(Ppu *p, int fg, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy) |
45 | 57 |
{ |
46 | 58 |
Uint16 v, h; |
47 |
- int ret = 0; |
|
48 | 59 |
for(v = 0; v < 8; v++) |
49 | 60 |
for(h = 0; h < 8; h++) { |
50 | 61 |
Uint8 ch1 = (sprite[v] >> (7 - h)) & 0x1; |
51 | 62 |
if(ch1 || blending[4][color]) |
52 |
- ret |= ppu_pixel(p, |
|
63 |
+ ppu_pixel(p, |
|
53 | 64 |
fg, |
54 | 65 |
x + (flipx ? 7 - h : h), |
55 | 66 |
y + (flipy ? 7 - v : v), |
56 | 67 |
blending[ch1][color]); |
57 | 68 |
} |
58 |
- return ret; |
|
59 | 69 |
} |
60 | 70 |
|
61 |
-unsigned int |
|
71 |
+void |
|
62 | 72 |
ppu_2bpp(Ppu *p, int fg, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy) |
63 | 73 |
{ |
64 | 74 |
Uint16 v, h; |
65 |
- int ret = 0; |
|
66 | 75 |
for(v = 0; v < 8; v++) |
67 | 76 |
for(h = 0; h < 8; h++) { |
68 | 77 |
Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1); |
69 | 78 |
Uint8 ch2 = ((sprite[v + 8] >> (7 - h)) & 0x1); |
70 | 79 |
Uint8 ch = ch1 + ch2 * 2; |
71 | 80 |
if(ch || blending[4][color]) |
72 |
- ret |= ppu_pixel(p, |
|
81 |
+ ppu_pixel(p, |
|
73 | 82 |
fg, |
74 | 83 |
x + (flipx ? 7 - h : h), |
75 | 84 |
y + (flipy ? 7 - v : v), |
76 | 85 |
blending[ch][color]); |
77 | 86 |
} |
78 |
- return ret; |
|
79 | 87 |
} |
80 | 88 |
|
81 | 89 |
/* output */ |
... | ... |
@@ -89,5 +97,6 @@ ppu_set_size(Ppu *p, Uint16 width, Uint16 height) |
89 | 97 |
p->dat = realloc(p->dat, p->stride * p->height * sizeof(unsigned int)); |
90 | 98 |
if(p->dat == NULL) return 0; |
91 | 99 |
ppu_clear(p); |
100 |
+ ppu_frame(p); |
|
92 | 101 |
return 1; |
93 |
-} |
|
94 | 102 |
\ No newline at end of file |
103 |
+} |
... | ... |
@@ -23,10 +23,12 @@ typedef unsigned int Uint32; |
23 | 23 |
|
24 | 24 |
typedef struct Ppu { |
25 | 25 |
Uint16 width, height; |
26 |
+ int i0, i1, redraw; |
|
26 | 27 |
unsigned int *dat, stride; |
27 | 28 |
} Ppu; |
28 | 29 |
|
30 |
+void ppu_frame(Ppu *p); |
|
29 | 31 |
int ppu_set_size(Ppu *p, Uint16 width, Uint16 height); |
30 |
-unsigned int ppu_pixel(Ppu *p, int fg, Uint16 x, Uint16 y, Uint8 color); |
|
31 |
-unsigned int ppu_1bpp(Ppu *p, int fg, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy); |
|
32 |
-unsigned int ppu_2bpp(Ppu *p, int fg, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy); |
|
32 |
+void ppu_pixel(Ppu *p, int fg, Uint16 x, Uint16 y, Uint8 color); |
|
33 |
+void ppu_1bpp(Ppu *p, int fg, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy); |
|
34 |
+void ppu_2bpp(Ppu *p, int fg, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy); |
... | ... |
@@ -122,17 +122,25 @@ get_pixel(int x, int y) |
122 | 122 |
static void |
123 | 123 |
redraw(Uxn *u) |
124 | 124 |
{ |
125 |
- Uint16 x, y; |
|
125 |
+ Uint16 x, y, y0 = 0, y1 = ppu.height; |
|
126 |
+ SDL_Rect up = gRect; |
|
126 | 127 |
if(devsystem->dat[0xe]) |
127 | 128 |
inspect(&ppu, u->wst.dat, u->wst.ptr, u->rst.ptr, u->ram.dat); |
128 |
- for(y = 0; y < ppu.height; ++y) |
|
129 |
+ if(ppu.redraw) { |
|
130 |
+ y0 = ppu.i0 / ppu.stride; |
|
131 |
+ y1 = ppu.i1 / ppu.stride + 1; |
|
132 |
+ up.y += y0; |
|
133 |
+ up.h = y1 - y0; |
|
134 |
+ } |
|
135 |
+ for(y = y0; y < y1; ++y) |
|
129 | 136 |
for(x = 0; x < ppu.width; ++x) |
130 | 137 |
ppu_screen[x + y * ppu.width] = palette[get_pixel(x, y)]; |
131 |
- SDL_UpdateTexture(gTexture, &gRect, ppu_screen, ppu.width * sizeof(Uint32)); |
|
138 |
+ SDL_UpdateTexture(gTexture, &up, ppu_screen + y0 * ppu.width, ppu.width * sizeof(Uint32)); |
|
132 | 139 |
SDL_RenderClear(gRenderer); |
133 | 140 |
SDL_RenderCopy(gRenderer, gTexture, NULL, NULL); |
134 | 141 |
SDL_RenderPresent(gRenderer); |
135 | 142 |
reqdraw = 0; |
143 |
+ ppu_frame(&ppu); |
|
136 | 144 |
} |
137 | 145 |
|
138 | 146 |
static void |
... | ... |
@@ -353,7 +361,7 @@ screen_talk(Device *d, Uint8 b0, Uint8 w) |
353 | 361 |
Uint16 x = peek16(d->dat, 0x8); |
354 | 362 |
Uint16 y = peek16(d->dat, 0xa); |
355 | 363 |
Uint8 layer = d->dat[0xe] & 0x40; |
356 |
- reqdraw |= ppu_pixel(&ppu, layer, x, y, d->dat[0xe] & 0x3); |
|
364 |
+ ppu_pixel(&ppu, layer, x, y, d->dat[0xe] & 0x3); |
|
357 | 365 |
if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 1); /* auto x+1 */ |
358 | 366 |
if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 1); /* auto y+1 */ |
359 | 367 |
break; |
... | ... |
@@ -364,10 +372,10 @@ screen_talk(Device *d, Uint8 b0, Uint8 w) |
364 | 372 |
Uint8 layer = d->dat[0xf] & 0x40; |
365 | 373 |
Uint8 *addr = &d->mem[peek16(d->dat, 0xc)]; |
366 | 374 |
if(d->dat[0xf] & 0x80) { |
367 |
- reqdraw |= ppu_2bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20); |
|
375 |
+ ppu_2bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20); |
|
368 | 376 |
if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 16); /* auto addr+16 */ |
369 | 377 |
} else { |
370 |
- reqdraw |= ppu_1bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20); |
|
378 |
+ ppu_1bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20); |
|
371 | 379 |
if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 8); /* auto addr+8 */ |
372 | 380 |
} |
373 | 381 |
if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 8); /* auto x+8 */ |
... | ... |
@@ -529,7 +537,7 @@ run(Uxn *u) |
529 | 537 |
} |
530 | 538 |
} |
531 | 539 |
uxn_eval(u, peek16(devscreen->dat, 0)); |
532 |
- if(reqdraw || devsystem->dat[0xe]) |
|
540 |
+ if(reqdraw || ppu.redraw || devsystem->dat[0xe]) |
|
533 | 541 |
redraw(u); |
534 | 542 |
if(!BENCH) { |
535 | 543 |
elapsed = (SDL_GetPerformanceCounter() - start) / (double)SDL_GetPerformanceFrequency() * 1000.0f; |