From c112bb835f56409e4afeefeb2d2b6c3684be5dee Mon Sep 17 00:00:00 2001 From: nattthebear Date: Tue, 20 Jun 2017 18:23:51 -0400 Subject: [PATCH] pizza: most things besides sound should be working now --- waterbox/pizza/lib/sgb.c | 180 +++++++++++++++++++++++++++++++++------ 1 file changed, 155 insertions(+), 25 deletions(-) diff --git a/waterbox/pizza/lib/sgb.c b/waterbox/pizza/lib/sgb.c index 993c56b2fd..162262b4df 100644 --- a/waterbox/pizza/lib/sgb.c +++ b/waterbox/pizza/lib/sgb.c @@ -27,6 +27,10 @@ typedef struct uint32_t palette[8][16]; uint32_t auxpalette[512][4]; + // border + uint8_t tiles[256][64]; // tiles stored in packed form + uint16_t tilemap[32 * 32]; + // frame data uint8_t frame[160 * 144]; // the most recent obtained full frame uint8_t frozenframe[160 * 144]; // the most recent saved full frame (MASK_EN) @@ -84,6 +88,9 @@ static void cmd_pal(int a, int b) for (int i = 0; i < 7; i++) c[i] = makecol(sgb.command[i * 2 + 1] | sgb.command[i * 2 + 2] << 8); sgb.palette[0][0] = c[0]; + sgb.palette[1][0] = c[0]; + sgb.palette[2][0] = c[0]; + sgb.palette[3][0] = c[0]; sgb.palette[a][1] = c[1]; sgb.palette[a][2] = c[2]; sgb.palette[a][3] = c[3]; @@ -101,11 +108,14 @@ static void cmd_pal_set(void) { if ((sgb.command[0] & 7) == 1) { + int p0 = sgb.command[1] | sgb.command[2] << 8 & 0x100; for (int i = 0; i < 4; i++) { int p = sgb.command[i * 2 + 1] | sgb.command[i * 2 + 2] << 8 & 0x100; - for (int j = 0; j < 4; j++) - sgb.palette[i][j] = sgb.auxpalette[p][j]; + sgb.palette[i][0] = sgb.auxpalette[p0][0]; + sgb.palette[i][1] = sgb.auxpalette[p][1]; + sgb.palette[i][2] = sgb.auxpalette[p][2]; + sgb.palette[i][3] = sgb.auxpalette[p][3]; } if (sgb.command[9] & 0x80) // change attribute { @@ -128,6 +138,57 @@ static void cmd_pal_set(void) static void cmd_attr_blk() { + int nset = sgb.command[1]; + if (nset <= 0 || nset >= 19) + { + utils_log("SGB: cmd_attr_blk bad nset"); + return; + } + int npacket = (nset * 6 + 16) / 16; + if ((sgb.command[0] & 7) != npacket) + { + utils_log("SGB: cmd_attr_blk bad length"); + return; + } + for (int i = 0; i < nset; i++) + { + int ctrl = sgb.command[i * 6 + 2] & 7; + int pals = sgb.command[i * 6 + 3]; + int x1 = sgb.command[i * 6 + 4]; + int y1 = sgb.command[i * 6 + 5]; + int x2 = sgb.command[i * 6 + 6]; + int y2 = sgb.command[i * 6 + 7]; + int inside = ctrl & 1; + int line = ctrl & 2; + int outside = ctrl & 4; + int insidepal = pals & 3; + int linepal = pals >> 2 & 3; + int outsidepal = pals >> 4 & 3; + if (ctrl == 1) + { + ctrl = 3; + linepal = insidepal; + } + else if (ctrl == 4) + { + ctrl = 6; + linepal = outsidepal; + } + uint8_t* dst = sgb.attr; + for (int y = 0; y < 18; y++) + { + for (int x = 0; x < 20; x++) + { + if (outside && (x < x1 || x > x2 || y < y1 || y > y2)) + *dst = outsidepal; + else if (inside && x > x1 && x < x2 && y > y1 && y < y2) + *dst = insidepal; + else if (line) + *dst = linepal; + dst++; + } + } + } } static void cmd_attr_lin() @@ -591,14 +652,14 @@ void sgb_set_controller_data(const uint8_t *buttons) static void trn_pal(const uint8_t *data) { const uint16_t *src = (const uint16_t *)data; - uint32_t *dst = (uint32_t *)sgb.auxpalette; + uint32_t *dst = sgb.auxpalette[0]; for (int i = 0; i < 2048; i++) dst[i] = makecol(src[i]); } static void trn_attr(const uint8_t *data) { - uint8_t *dst = (uint8_t *)sgb.auxattr; + uint8_t *dst = sgb.auxattr[0]; for (int n = 0; n < 45 * 90; n++) { uint8_t s = *data++; @@ -609,7 +670,41 @@ static void trn_attr(const uint8_t *data) } } -#include "mmu.h" +static void trn_pct(const uint8_t* data) +{ + memcpy(sgb.tilemap, data, sizeof(sgb.tilemap)); + const uint16_t* palettes = (const uint16_t*)(data + sizeof(sgb.tilemap)); + uint32_t* dst = sgb.palette[4]; + for (int i = 0; i < 64; i++) + dst[i] = makecol(palettes[i]); +} + +static void trn_chr(const uint8_t* data, int bank) +{ + uint8_t* dst = sgb.tiles[128 * bank]; + for (int n = 0; n < 128; n++) + { + for (int y = 0; y < 8; y++) + { + int a = data[0]; + int b = data[1] << 1; + int c = data[16] << 2; + int d = data[17] << 3; + for (int x = 7; x >= 0; x--) + { + dst[x] = a & 1 | b & 2 | c & 4 | d & 8; + a >>= 1; + b >>= 1; + c >>= 1; + d >>= 1; + } + dst += 8; + data += 2; + } + data += 16; + } +} + static void do_vram_transfer(void) { uint8_t vram[4096]; @@ -653,10 +748,13 @@ static void do_vram_transfer(void) trn_pal(vram); break; case TRN_CHR_LOW: + trn_chr(vram, 0); break; case TRN_CHR_HI: + trn_chr(vram, 1); break; case TRN_PCT: + trn_pct(vram); break; case TRN_ATTR: trn_attr(vram); @@ -690,26 +788,6 @@ void sgb_take_frame(uint32_t *vbuff) static void sgb_render_frame_gb(uint32_t *vbuff) { - /*sgb.palette[0][0] = 0xff000000; - sgb.palette[0][1] = 0xff550055; - sgb.palette[0][2] = 0xffaa00aa; - sgb.palette[0][3] = 0xffff00ff; - - sgb.palette[1][0] = 0xff00003f; - sgb.palette[1][1] = 0xff00007f; - sgb.palette[1][2] = 0xff0000bf; - sgb.palette[1][3] = 0xff0000ff; - - sgb.palette[2][0] = 0xff003f00; - sgb.palette[2][1] = 0xff007f00; - sgb.palette[2][2] = 0xff00bf00; - sgb.palette[2][3] = 0xff00ff00; - - sgb.palette[3][0] = 0xff3f0000; - sgb.palette[3][1] = 0xff7f0000; - sgb.palette[3][2] = 0xffbf0000; - sgb.palette[3][3] = 0xffff0000;*/ - const uint8_t *attr = sgb.attr; const uint8_t *src = sgb.active_mask ? sgb.frozenframe : sgb.frame; uint32_t *dst = vbuff + ((224 - 144) / 2 * 256 + (256 - 160) / 2); @@ -726,7 +804,59 @@ static void sgb_render_frame_gb(uint32_t *vbuff) } } +static void draw_tile(uint16_t entry, uint32_t* dest) +{ + const uint8_t* tile = sgb.tiles[entry & 0xff]; + const uint32_t* palette = sgb.palette[entry >> 10 & 7]; + int hflip = entry & 0x4000; + int vflip = entry & 0x8000; + int hinc, vinc; + if (hflip) + { + hinc = -1; + dest += 7; + } + else + { + hinc = 1; + } + if (vflip) + { + vinc = -256; + dest += 7 * 256; + } + else + { + vinc = 256; + } + vinc -= 8 * hinc; + for (int y = 0; y < 8; y++, dest += vinc) + { + for (int x = 0; x < 8; x++, dest += hinc) + { + int c = *tile++; + if (c) + *dest = palette[c]; + } + } +} + +static void sgb_render_border(uint32_t*vbuff) +{ + const uint16_t* tilemap = sgb.tilemap; + for (int n = 0; n < 32 * 28; n++) + { + draw_tile(*tilemap++, vbuff); + vbuff += 8; + if ((n & 31) == 31) + vbuff += 256 * 7; + } +} + void sgb_render_frame(uint32_t *vbuff) { + for (int i = 0; i < 256 * 224; i++) + vbuff[i] = sgb.palette[0][0]; sgb_render_frame_gb(vbuff); + sgb_render_border(vbuff); }