From ff6e784e7c5ebe223666c6c631305397ad358289 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 23 Apr 2023 15:48:59 +0200 Subject: Start decoupling of rendering from update passes --- src/renderer_m0.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'src/renderer_m0.c') diff --git a/src/renderer_m0.c b/src/renderer_m0.c index 8bd4263..00874ea 100644 --- a/src/renderer_m0.c +++ b/src/renderer_m0.c @@ -615,6 +615,84 @@ draw_icn(size_t x, size_t y, u8 *sprite, u8 clr, u8 flip_x, u8 flip_y) { dirty_tiles[tile_y] |= dirty; } +IWRAM_CODE +void +draw_tile(size_t x, size_t y, Tile *tile, u8 clr) { + BOUNDCHECK_SCREEN(x, y); + size_t tile_x0 = x / 8; + size_t tile_x1 = (x + 7) / 8; + size_t tile_y = y / 8; + size_t start_col = x % 8; + size_t start_row = y % 8; + size_t shift_left = start_col * 4; + size_t shift_right = (8 - start_col) * 4; + u32 dirty = (1 << tile_x0) | (1 << tile_x1); + u32 *dst = &backbuf[start_row + (tile_x0 + tile_y * 32) * 8]; + // BOUNDCHECK_SCREEN(x, y); + + // // Find row position for the given x/y coordinates. + // size_t tile_x = x / 8; + // size_t tile_y = y / 8; + // size_t start_col = x % 8; + // size_t start_row = y % 8; + + // // Get a pointer to the backbuffer and the tile row. + // size_t pos = start_row + (tile_x + tile_y * 32) * 8; + // u32 *backbuffer = &BACKBUF[pos]; + u32 *row = tile; + u32 row_mask_left = 0xFFFFFFFF << shift_left; + u32 row_mask_right = 0xFFFFFFFF >> shift_right; + + // Draw the tiles. There are 4 possible cases: + // 1. The tile is exactly at the tile boundary. + // 2. The tile spans 2 tiles horizontally. + // 3. The tile spans 2 tiles vertically. + // 4. The tile spans 4 tiles. + if (start_col == 0 && start_row == 0) { + for (size_t i = 0; i < (8 - start_row); i++, dst++) { + BOUNDCHECK_SCREEN(x, y + i); + dst[0] = (dst[0] & ~row_mask_left) | row[i] * clr; + } + dirty_tiles[tile_y] |= 1 << tile_x0; + } else if (start_row == 0) { + for (size_t i = 0; i < 8; i++, dst++) { + BOUNDCHECK_SCREEN(x, y + i); + dst[0] = (dst[0] & ~row_mask_left) | (row[i] * clr << shift_left); + dst[8] = (dst[8] & ~row_mask_right) | (row[i] * clr >> shift_right); + } + dirty_tiles[tile_y] |= 1 << tile_x0; + dirty_tiles[tile_y] |= 1 << (tile_x0 + 1); + } else if (start_col == 0) { + for (size_t i = 0; i < (8 - start_row); i++, dst++) { + BOUNDCHECK_SCREEN(x, y + i); + dst[0] = (dst[0] & ~row_mask_left) | row[i] * clr; + } + dst += 8 * 31; + for (size_t i = (8 - start_row); i < 8; i++, dst++) { + BOUNDCHECK_SCREEN(x, y + i); + dst[0] = (dst[0] & ~row_mask_left) | row[i] * clr; + } + dirty_tiles[tile_y] |= 1 << tile_x0; + dirty_tiles[tile_y + 1] |= 1 << tile_x0; + } else { + for (size_t i = 0; i < (8 - start_row); i++, dst++) { + BOUNDCHECK_SCREEN(x, y + i); + dst[0] = (dst[0] & ~row_mask_left) | (row[i] * clr << shift_left); + dst[8] = (dst[8] & ~row_mask_right) | (row[i] * clr >> shift_right); + } + dst += 8 * 31; + for (size_t i = (8 - start_row); i < 8; i++, dst++) { + BOUNDCHECK_SCREEN(x, y + i); + dst[0] = (dst[0] & ~row_mask_left) | (row[i] * clr << shift_left); + dst[8] = (dst[8] & ~row_mask_right) | (row[i] * clr >> shift_right); + } + dirty_tiles[tile_y] |= 1 << tile_x0; + dirty_tiles[tile_y] |= 1 << (tile_x0 + 1); + dirty_tiles[tile_y + 1] |= 1 << tile_x0; + dirty_tiles[tile_y + 1] |= 1 << (tile_x0 + 1); + } +} + // // Flipping buffers/copying memory. // -- cgit v1.2.1