Update ppu to use current version of screen talk

This commit is contained in:
Bad Diode 2022-03-04 17:28:46 +01:00
parent 232f303cf1
commit 43eaa37472
5 changed files with 71 additions and 32 deletions

View File

@ -2,7 +2,7 @@ BASE_UXN := src/uxn/src
SRC_DIR ?= src
BUILD_DIR ?= build
SRC_MAIN ?= $(SRC_DIR)/main.c
EXE_NAME ?= fbtest
EXE_NAME ?= uxnfb
BIN := $(BUILD_DIR)/$(EXE_NAME)
UXN_HEAD := $(BASE_UXN)/uxn.h

View File

@ -89,22 +89,56 @@ system_talk(Device *d, u8 b0, u8 w) {
void
screen_talk(Device *d, u8 b0, u8 w) {
if(w && b0 == 0xe) {
Uint16 x = mempeek16(d->dat, 0x8);
Uint16 y = mempeek16(d->dat, 0xa);
Uint8 layer = d->dat[0xe] >> 4 & 0x1;
ppu_pixel(layer, x, y, d->dat[0xe] & 0x3);
reqdraw = 1;
} else if(w && b0 == 0xf) {
Uint16 x = mempeek16(d->dat, 0x8);
Uint16 y = mempeek16(d->dat, 0xa);
Uint8 layer = d->dat[0xf] >> 0x6 & 0x1;
Uint8 *addr = &d->mem[mempeek16(d->dat, 0xc)];
if(d->dat[0xf] >> 0x7 & 0x1)
ppu_2bpp(layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1);
else
ppu_1bpp(layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1);
reqdraw = 1;
if (w) {
switch (b0) {
case 0x1: {
d->vector = mempeek16(d->dat, 0x0);
} break;
case 0xe: {
u16 x = mempeek16(d->dat, 0x8);
u16 y = mempeek16(d->dat, 0xa);
u8 *addr = &d->mem[mempeek16(d->dat, 0xc)];
u8 *layer = d->dat[0xe] >> 4 & 0x1 ? pixels_fg : pixels_bg;
u8 mode = d->dat[0xe] >> 5;
u8 color = d->dat[0xf] & 0xf;
if(!mode) {
ppu_pixel(layer, x, y, d->dat[0xe] & 0x3);
} else if(mode-- & 0x1) {
u8 flipx = mode & 0x2;
u8 flipy = mode & 0x4;
ppu_1bpp(layer, x, y, addr, color, flipx, flipy);
} else {
u8 flipx = mode & 0x2;
u8 flipy = mode & 0x4;
ppu_2bpp(layer, x, y, addr, color, flipx, flipy);
}
if(d->dat[0x6] & 0x01) { mempoke16(d->dat, 0x8, x + 1); }
if(d->dat[0x6] & 0x02) { mempoke16(d->dat, 0xa, y + 1); }
} break;
case 0xf: {
u16 x = mempeek16(d->dat, 0x8);
u16 y = mempeek16(d->dat, 0xa);
u8 *addr = &d->mem[mempeek16(d->dat, 0xc)];
u8 *layer = d->dat[0xf] >> 6 & 0x1 ? pixels_fg : pixels_bg;
u8 color = d->dat[0xf] & 0xf;
u8 flipx = (d->dat[0xf] >> 0x4) & 0x1;
u8 flipy = (d->dat[0xf] >> 0x5) & 0x1;
if(d->dat[0xf] >> 0x7 & 0x1) {
ppu_2bpp(layer, x, y, addr, color, flipx, flipy);
if(d->dat[0x6] & 0x04) {
mempoke16(d->dat, 0xc, mempeek16(d->dat, 0xc) + 16);
}
} else {
ppu_1bpp(layer, x, y, addr, color, flipx, flipy);
if(d->dat[0x6] & 0x04) {
mempoke16(d->dat, 0xc, mempeek16(d->dat, 0xc) + 8);
}
}
if(d->dat[0x6] & 0x01) { mempoke16(d->dat, 0x8, x + 8); }
if(d->dat[0x6] & 0x02) { mempoke16(d->dat, 0xa, y + 8); }
} break;
default: break;
}
}
}

View File

@ -21,7 +21,8 @@ static size_t screen_height = 0;
static u32 *framebuffer = 0;
static u32 palette[16];
static u8 *pixels_buf;
static u8 *pixels_fg;
static u8 *pixels_bg;
static u8 *dirty_lines;
static u8 reqdraw = 0;
// TODO: Probably should consider this
@ -35,17 +36,18 @@ static u8 blending[5][16] = {
{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}};
void
ppu_pixel(u8 layer, u16 x, u16 y, u8 color) {
size_t idx = y * screen_width + x;
u8 *pixel = &pixels_buf[idx], shift = layer * 2;
if(x < screen_width && y < screen_height) {
*pixel = (*pixel & ~(0x3 << shift)) | (color << shift);
}
ppu_pixel(u8 *layer, u16 x, u16 y, u8 color) {
if(x < screen_width && y < screen_height) {
Uint32 i = x + y *screen_width;
if(color != layer[i]) {
layer[i] = color;
}
}
dirty_lines[y] |= 1;
}
void
ppu_1bpp(u8 layer, u16 x, u16 y, u8 *sprite, u8 color, u8 flipx, u8 flipy) {
ppu_1bpp(u8 *layer, u16 x, u16 y, u8 *sprite, u8 color, u8 flipx, u8 flipy) {
u16 v, h;
for(v = 0; v < 8; v++)
for(h = 0; h < 8; h++) {
@ -59,7 +61,7 @@ ppu_1bpp(u8 layer, u16 x, u16 y, u8 *sprite, u8 color, u8 flipx, u8 flipy) {
}
void
ppu_2bpp(u8 layer, u16 x, u16 y, u8 *sprite, u8 color, u8 flipx, u8 flipy) {
ppu_2bpp(u8 *layer, u16 x, u16 y, u8 *sprite, u8 color, u8 flipx, u8 flipy) {
u16 v, h;
for(v = 0; v < 8; v++)
for(h = 0; h < 8; h++) {
@ -106,7 +108,8 @@ ppu_init(void) {
}
// Allocate intermediate buffers.
pixels_buf = malloc(screen_width * screen_height);
pixels_fg = malloc(screen_width * screen_height);
pixels_bg = malloc(screen_width * screen_height);
dirty_lines = malloc(screen_height);
// Initialize default palette.
@ -116,7 +119,8 @@ ppu_init(void) {
palette[3] = 0xff7777;
// Clear pixel buffer memory.
memset(pixels_buf, 0, screen_width * screen_height);
memset(pixels_fg, 0, screen_width * screen_height);
memset(pixels_bg, 0, screen_width * screen_height);
memset(dirty_lines, 1, screen_height);
// Make sure we perform an initial screen drawing.
@ -135,7 +139,7 @@ blit_framebuffer(void) {
if (dirty_lines[j] != 0) {
for (size_t i = 0; i < screen_width; i++) {
size_t idx = i + j * screen_width;
framebuffer[idx] = palette[pixels_buf[idx] % 16];
framebuffer[idx] = palette[pixels_fg[idx] << 2 | pixels_bg[idx]];
}
}
dirty_lines[j] = 0;

View File

@ -15,6 +15,6 @@ typedef unsigned short Uint16;
typedef unsigned int Uint32;
int ppu_init(void);
void ppu_pixel(Uint8 layer, Uint16 x, Uint16 y, Uint8 color);
void ppu_1bpp(Uint8 layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy);
void ppu_2bpp(Uint8 layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy);
void ppu_pixel(Uint8 *layer, Uint16 x, Uint16 y, Uint8 color);
void ppu_1bpp(Uint8 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy);
void ppu_2bpp(Uint8 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy);

View File

@ -29,6 +29,7 @@ typedef struct {
typedef struct Device {
struct Uxn *u;
Uint8 addr, dat[16], *mem;
u16 vector;
void (*talk)(struct Device *d, Uint8, Uint8);
} Device;