| ... | ... |
@@ -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; |