From 98eb21a9e2b106c6b927964e54b93061955cd6bc Mon Sep 17 00:00:00 2001 From: condret Date: Wed, 6 Nov 2024 04:41:04 +0100 Subject: [PATCH] Minor progress gb_ppu_render_continue --- include/gb.h | 5 ++++ io/ppu.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/include/gb.h b/include/gb.h index 60bc6d6..a0f7eb5 100644 --- a/include/gb.h +++ b/include/gb.h @@ -5,6 +5,11 @@ #include #include +#define WHITE 0x86c06c +#define LIGHT_GRAY 0xe0f8cf +#define DARK_GRAY 0 +#define BLACK 0 + enum { GB_TIMERS_DIV = 0, GB_TIMERS_TIMA, diff --git a/io/ppu.c b/io/ppu.c index 6ff93e9..e33e765 100644 --- a/io/ppu.c +++ b/io/ppu.c @@ -144,10 +144,11 @@ static ut32 gb_ppu_oam_scan_continue (GB *gb, ut32 cycles) { while (cycles && gb->ppu->ost.addr <= 0xa0) { if (gb->ppu->ost.n_entries < 10) { ut8 yx[2]; + //this is probably inaccurate r_io_fd_read_at (gb->io, gb->dma->oam_fd, (ut64)gb->ppu->ost.addr, yx, 2); - if ((yx[0] <= ly) && (ly < (yx[0] + height)) && yx[1]) { + if ((yx[0] <= ly) && (ly < (yx[0] + height))) { gb->ppu->ost.data[gb->ppu->ost.n_entries] = - (gb->ppu->ost.addr << 16) | (yx[0] << 8) | yx[0]; + (gb->ppu->ost.addr << 16) | (yx[0] << 8) | yx[1]; gb->ppu->ost.n_entries++; } } @@ -196,7 +197,7 @@ static void read_obj_data (GBPPU *ppu, RIO *io, ut8 *tile, int oam_fd) { } } -static void gb_ppu_pixel_fifo_merge_opixels (PixelFifo *pxf, bool priority) { +static void gb_ppu_pixel_fifo_merge_opixels (PixelFifo *pxf) { ut32 pixels = pxf->data >> 32; ut32 newpixels = 0; ut32 i; @@ -311,6 +312,9 @@ static void gb_pixel_fifo_fetch_continue (GB *gb) { } fifo->fetcher[1].fetched |= (fifo->obj & GB_FIFO_OAM_PALLET)? 0xcccccccc: 0x88888888; + if ((fifo->obj & 0xff) < 8) { //is this correct? + fifo->fetcher[1].fetched <<= ((8 - (fifo->obj & 0xff)) << 2); + } } break; case 7: @@ -321,6 +325,56 @@ static void gb_pixel_fifo_fetch_continue (GB *gb) { fifo->fetcher[fetch_obj].state_ctr = (fifo->fetcher[fetch_obj].state_ctr + 1) & 0x7; } +static bool check_objects (GBPPU *ppu) { + if (!ppu->fifo.x) { + return false; + } + ut32 i; + for (i = 0; i < ppu->ost.n_entries; i++) { + const ut8 x = ppu->ost.data[i] & 0xff; + //x cannot be 0, because oam entries with x = 0 don't end in this array + //because of this setting x to 0 can be used to invalidate entries + if (x && (x == ppu->fifo.x)) { + ppu->fifo.obj = ppu->ost.data[i]; +#if 0 + ppu->ost.data[i] &= 0xffffff00; +#else + ppu->ost.data[i] = 0; +#endif + return true; + } + } + return false; +} + +static void shit_out_pixel (GBPPU *ppu) { + ppu->fifo.shift_out = (ppu->fifo.shift_out & 0xf0) | ppu->fifo.data >> 60; + ppu->fifo.data = ppu->fifo.data << 4; + ppu->fifo.n_fpixel--; + if (ppu->fifo.dx) { + //discard pixel + ppu->fifo.dx--; + return; + } + ut8 color; + if (!(ppu->fifo.shift_out & 0x08)) { + //bg pallet + color = (ppu->buf[GB_PPU_BGP] & (0x3 << ((ppu->fifo.shift_out & 0x3) << 1))) >> + ((ppu->fifo.shift_out & 0x3) << 1); + } else { + const ut8 pal = !!(ppu->fifo.shift_out & 0x04); + color = (ppu->buf[GB_PPU_OBP0 + pal] & (0x3 << ((ppu->fifo.shift_out & 0x3) << 1))) >> + ((ppu->fifo.shift_out & 0x3) << 1); + } +#if 0 + if (ppu->fifo.x > 7) { //is this correct? + gb_pix_buf_set_pixel (ppu->pixbuf, ppu->fifo.x, ppu->buf[GB_PPU_LY], color); + } +#endif + gb_pix_buf_set_pixel (ppu->pixbuf, ppu->fifo.x, ppu->buf[GB_PPU_LY], color); + ppu->fifo.x++; +} + static void gb_ppu_render_launch (GB *gb) { RIOMap *vram = r_io_map_get (gb->io, gb->ppu->vram_mapid); vram->perm = 0; //disable vram access for rendering @@ -337,6 +391,8 @@ static ut32 gb_ppu_render_continue (GB *gb, ut32 cycles) { } while (cycles) { if (fifo->n_fpixel < 9) { + //initial phase on each line + //also when window starts? gb_pixel_fifo_fetch_continue (gb); if (fifo->flags & GB_PIXEL_FIFO_FETCH_READY) { if (!fifo->n_fpixel) { @@ -350,6 +406,26 @@ static ut32 gb_ppu_render_continue (GB *gb, ut32 cycles) { fifo->flags ^= GB_PIXEL_FIFO_FETCH_READY; fifo->fetcher[0].state_ctr = 0; } + } else { + if (!(fifo->flags & GB_PIXEL_FIFO_FETCH_OBJECT)) { + if (check_objects (gb->ppu)) { + fifo->flags |= GB_PIXEL_FIFO_FETCH_OBJECT; + } else { + shit_out_pixel (gb->ppu); + } + gb_pixel_fifo_fetch_continue (gb); + if (fifo->n_fpixel < 9 && (fifo->flags & GB_PIXEL_FIFO_FETCH_READY)) { + fifo->data |= fifo->fetcher[0].fetched; + fifo->n_fpixel += 8; + fifo->flags ^= GB_PIXEL_FIFO_FETCH_READY; + } + } else { + gb_pixel_fifo_fetch_continue (gb); + if (fifo->flags & GB_PIXEL_FIFO_FETCH_READY) { + gb_ppu_pixel_fifo_merge_opixels (fifo); + fifo->flags ^= GB_PIXEL_FIFO_FETCH_OBJECT | GB_PIXEL_FIFO_FETCH_READY; + } + } } fifo->remaining_cycles--; cycles--;