From 96c4179094b229c67701f0f36abd5e118a4331c9 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 6 Jun 2021 10:58:09 +0200 Subject: Add diagonal line implementation --- src/renderer.c | 103 +++++++++++++++++++++------------------------------------ 1 file changed, 37 insertions(+), 66 deletions(-) (limited to 'src/renderer.c') diff --git a/src/renderer.c b/src/renderer.c index d247d06..2b1f0d2 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -47,65 +47,6 @@ draw_pixel(size_t x, size_t y, u8 color) { IWRAM_CODE void draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { - // Pointer to the initial position of the screen buffer where we will start - // writing our data. - // vu16 *destination = (u16*)(SCREEN_BUFFER + y0 * SCREEN_WIDTH + x0); - -// // Adjust the step direction and calculate deltas. -// size_t x_step; -// size_t y_step; -// size_t dx; -// size_t dy; -// if (x0 > x1) { -// x_step = -1; -// dx = x0 - x1; -// } else { -// x_step = 1; -// dx = x1 - x0; -// } -// if (y0 > y1) { -// y_step = -SCREEN_WIDTH; -// dy = y0 - y1; -// } else { -// y_step = +SCREEN_WIDTH; -// dy = y1 - y0; -// } - -// if(dy == 0) { -// // Horizontal line. -// for(int i = 0; i <= dx; i++) { -// draw_pixel(x0 + i, y0, clr); -// } -// } else if(dx == 0) { -// // Vertical line. -// for(int i = 0; i <= dy; i++) { -// draw_pixel(x0, y0 + i, clr); -// } -// } else if (dx >= dy){ -// // Positive slope. -// int diff = 2 * dy - dx; -// for (int i = 0; i <= dx; ++i) { -// // *destination = clr; -// if (diff >= 0) { -// // destination += y_step; -// diff -= 2 * dx; -// } -// // destination += x_step; -// diff += 2 * dy; -// } -// } else { -// // Negative slope. -// int diff = 2 * dx - dy; -// for (int i = 0; i <= dy; ++i) { -// // *destination = clr; -// if (diff >= 0) { -// // destination += x_step; -// diff -= 2 * dy; -// } -// // destination += y_step; -// diff += 2 * dx; -// } -// } BOUNDCHECK_SCREEN(x0, y0); BOUNDCHECK_SCREEN(x1, y1); @@ -122,15 +63,13 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { // Get a pointer to the backbuffer and the tile row. u32 *backbuffer = &BACKBUF[start_row0 + (tile_x0 + tile_y0 * 32) * 8]; - size_t dx = tile_x1 - tile_x0; - size_t dy = tile_y1 - tile_y0; - if (y0 == y1) { - // There are 3 cases: + // Horizontal line. There are 3 cases: // 1. Lines fit on a single tile. // 2. Lines go through 2 tiles, both require partial row updates. // 3. Lines go through 3 or more tiles, first and last tiles use // partial row updates, rows in the middle can write the. + size_t dx = tile_x1 - tile_x0; if (dx < 1) { u32 row_mask = 0xFFFFFFFF; row_mask >>= (7 - start_col1 - dx) * 4; @@ -155,7 +94,8 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { dirty_tiles[tile_y0] |= 1 << (tile_x0 + dx); } } else if (x0 == x1) { - //The vertical line cases are analogous to the horizontal ones. + // Vertical line. The cases are analogous to the horizontal ones. + size_t dy = tile_y1 - tile_y0; u32 row_mask = 0xF << start_col0 * 4; u32 row_left = (0x11111111 * clr) & row_mask; if (dy < 1) { @@ -178,9 +118,40 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { backbuffer[0] = (backbuffer[0] & ~row_mask) | row_left; } } + } else { + // Diagonal line. + int x_step = x0 > x1 ? -1 : 1; + int y_step = y0 > y1 ? -1 : 1; + size_t dx = x0 > x1 ? x0 - x1 : x1 - x0; + size_t dy = y0 > y1 ? y0 - y1 : y1 - y0; + size_t x = x0; + size_t y = y0; + if (dx >= dy) { + // Positive slope. + int diff = 2 * dy - dx; + for (int i = 0; i <= dx; ++i) { + draw_pixel(x, y, clr); + if (diff >= 0) { + y += y_step; + diff -= 2 * dx; + } + x += x_step; + diff += 2 * dy; + } + } else { + // Negative slope. + int diff = 2 * dx - dy; + for (int i = 0; i <= dy; ++i) { + draw_pixel(x, y, clr); + if (diff >= 0) { + x += x_step; + diff -= 2 * dy; + } + y -= y_step; + diff += 2 * dx; + } + } } - - // TODO: Add slope line drawing. } IWRAM_CODE -- cgit v1.2.1