From 0bc1022b676894f87ff9222c1ec931b83c31daca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Jahoda?= Date: Mon, 27 Nov 2017 21:32:27 +0100 Subject: [PATCH 1/4] Speed up drawTile. Clip the tile in all orientations. Speed up blitting for scale=1. --- src/tic.c | 70 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/src/tic.c b/src/tic.c index bddbef3..983f319 100644 --- a/src/tic.c +++ b/src/tic.c @@ -20,6 +20,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +#include #include #include #include @@ -244,39 +245,54 @@ static void drawRectBorder(tic_machine* machine, s32 x, s32 y, s32 width, s32 he drawVLine(machine, x + width - 1, y, height, color); } +#define DRAW_TILE_BODY(index_expr) ({\ + y += sy; \ + for(s32 py=sy; py < ey; py++, y++) \ + { \ + s32 xx = x + sx; \ + for(s32 px=sx; px < ex; px++, xx++) \ + { \ + u8 color = mapping[tic_tool_peek4(buffer, index_expr)]; \ + if(color != 255) tic_tool_poke4(machine->memory.ram.vram.screen.data, y * TIC80_WIDTH + xx, color); \ + } \ + } \ + }) + static void drawTile(tic_machine* machine, const tic_tile* buffer, s32 x, s32 y, u8* colors, s32 count, s32 scale, tic_flip flip, tic_rotate rotate) { - static u8 transparent[TIC_PALETTE_SIZE]; - memset(transparent, 0, sizeof(transparent)); - for (s32 i = 0; i < count; i++) transparent[colors[i]] = 1; + static u8 mapping[TIC_PALETTE_SIZE]; + for (s32 i = 0; i < TIC_PALETTE_SIZE; i++) mapping[i] = tic_tool_peek4(machine->memory.ram.vram.mapping, i); + for (s32 i = 0; i < count; i++) mapping[colors[i]] = 255; - flip &= 0b11; rotate &= 0b11; + u32 orientation = flip & 0b11; - if (flip == 0 && rotate == 0 && scale == 1) { + if(rotate == tic_90_rotate) orientation ^= 0b001; + else if(rotate == tic_180_rotate) orientation ^= 0b011; + else if(rotate == tic_270_rotate) orientation ^= 0b010; + if (rotate == tic_90_rotate || rotate == tic_270_rotate) orientation |= 0b100; + + if (scale == 1) { // the most common path - s32 i = 0; - for(s32 py=0; py < TIC_SPRITESIZE; py++, y++) - { - s32 xx = x; - for(s32 px=0; px < TIC_SPRITESIZE; px++, xx++) - { - u8 color = tic_tool_peek4(buffer, i++); - if(!transparent[color]) setPixel(machine, xx, y, color); - } + s32 sx, sy, ex, ey; + sx = machine->state.clip.l - x; if (sx < 0) sx = 0; + sy = machine->state.clip.t - y; if (sy < 0) sy = 0; + ex = machine->state.clip.r - x; if (ex > TIC_SPRITESIZE) ex = TIC_SPRITESIZE; + ey = machine->state.clip.b - y; if (ey > TIC_SPRITESIZE) ey = TIC_SPRITESIZE; + switch (orientation) { + case 0b100: DRAW_TILE_BODY(px * TIC_SPRITESIZE + py); break; + case 0b110: DRAW_TILE_BODY(px * TIC_SPRITESIZE + TIC_SPRITESIZE - py - 1); break; + case 0b101: DRAW_TILE_BODY((TIC_SPRITESIZE - px - 1) * TIC_SPRITESIZE + py); break; + case 0b111: DRAW_TILE_BODY((TIC_SPRITESIZE - px) * TIC_SPRITESIZE - py - 1); break; + case 0b000: DRAW_TILE_BODY(py * TIC_SPRITESIZE + px); break; + case 0b010: DRAW_TILE_BODY((TIC_SPRITESIZE - py - 1) * TIC_SPRITESIZE + px); break; + case 0b001: DRAW_TILE_BODY(py * TIC_SPRITESIZE + TIC_SPRITESIZE - px - 1); break; + case 0b011: DRAW_TILE_BODY((TIC_SPRITESIZE - py) * TIC_SPRITESIZE - px - 1); break; + default: assert(!"Unknown value of orientation in drawTile"); } return; } - s32 a = flip & tic_horz_flip ? -1 : 1; - s32 b = flip & tic_vert_flip ? -1 : 1; - - if(rotate == tic_90_rotate) a = -a; - else if(rotate == tic_180_rotate) a = -a, b = -b; - else if(rotate == tic_270_rotate) b = -b; - - bool swap_axis = (rotate == tic_90_rotate || rotate == tic_270_rotate); - for(s32 py=0; py < TIC_SPRITESIZE; py++, y+=scale) { s32 xx = x; @@ -284,15 +300,15 @@ static void drawTile(tic_machine* machine, const tic_tile* buffer, s32 x, s32 y, { s32 i; s32 ix, iy; - ix = a == 1 ? px : TIC_SPRITESIZE - px - 1; - iy = b == 1 ? py : TIC_SPRITESIZE - py - 1; - if(swap_axis) { + ix = orientation & 0b001 ? TIC_SPRITESIZE - px - 1: px; + iy = orientation & 0b010 ? TIC_SPRITESIZE - py - 1: py; + if(orientation & 0b100) { i = ix * TIC_SPRITESIZE + iy; } else { i = iy * TIC_SPRITESIZE + ix; } u8 color = tic_tool_peek4(buffer, i); - if(!transparent[color]) { + if(mapping[color] != 255) { if (scale == 1) { setPixel(machine, xx, y, color); } else { From 2af202e5ec0f0cb485b9690ee709c42c6946ea71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Jahoda?= Date: Fri, 1 Dec 2017 21:37:36 +0100 Subject: [PATCH 2/4] Prettify macro --- src/tic.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/tic.c b/src/tic.c index 983f319..db2f048 100644 --- a/src/tic.c +++ b/src/tic.c @@ -258,6 +258,9 @@ static void drawRectBorder(tic_machine* machine, s32 x, s32 y, s32 width, s32 he } \ }) +#define REVERT(X) (TIC_SPRITESIZE - 1 - (X)) +#define INDEX_XY(X, Y) ((Y) * TIC_SPRITESIZE + (X)) + static void drawTile(tic_machine* machine, const tic_tile* buffer, s32 x, s32 y, u8* colors, s32 count, s32 scale, tic_flip flip, tic_rotate rotate) { static u8 mapping[TIC_PALETTE_SIZE]; @@ -280,14 +283,14 @@ static void drawTile(tic_machine* machine, const tic_tile* buffer, s32 x, s32 y, ex = machine->state.clip.r - x; if (ex > TIC_SPRITESIZE) ex = TIC_SPRITESIZE; ey = machine->state.clip.b - y; if (ey > TIC_SPRITESIZE) ey = TIC_SPRITESIZE; switch (orientation) { - case 0b100: DRAW_TILE_BODY(px * TIC_SPRITESIZE + py); break; - case 0b110: DRAW_TILE_BODY(px * TIC_SPRITESIZE + TIC_SPRITESIZE - py - 1); break; - case 0b101: DRAW_TILE_BODY((TIC_SPRITESIZE - px - 1) * TIC_SPRITESIZE + py); break; - case 0b111: DRAW_TILE_BODY((TIC_SPRITESIZE - px) * TIC_SPRITESIZE - py - 1); break; - case 0b000: DRAW_TILE_BODY(py * TIC_SPRITESIZE + px); break; - case 0b010: DRAW_TILE_BODY((TIC_SPRITESIZE - py - 1) * TIC_SPRITESIZE + px); break; - case 0b001: DRAW_TILE_BODY(py * TIC_SPRITESIZE + TIC_SPRITESIZE - px - 1); break; - case 0b011: DRAW_TILE_BODY((TIC_SPRITESIZE - py) * TIC_SPRITESIZE - px - 1); break; + case 0b100: DRAW_TILE_BODY(INDEX_XY(py, px)); break; + case 0b110: DRAW_TILE_BODY(INDEX_XY(REVERT(py), px)); break; + case 0b101: DRAW_TILE_BODY(INDEX_XY(py, REVERT(px))); break; + case 0b111: DRAW_TILE_BODY(INDEX_XY(REVERT(py), REVERT(px))); break; + case 0b000: DRAW_TILE_BODY(INDEX_XY(px, py)); break; + case 0b010: DRAW_TILE_BODY(INDEX_XY(px, REVERT(py))); break; + case 0b001: DRAW_TILE_BODY(INDEX_XY(REVERT(px), py)); break; + case 0b011: DRAW_TILE_BODY(INDEX_XY(REVERT(px), REVERT(py))); break; default: assert(!"Unknown value of orientation in drawTile"); } return; From 21312e2cd39c1dd523f3b9d520c3aacf1133ab3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Jahoda?= Date: Sun, 3 Dec 2017 22:19:40 +0100 Subject: [PATCH 3/4] Minor styling changes. --- src/tic.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/tic.c b/src/tic.c index db2f048..19e66b1 100644 --- a/src/tic.c +++ b/src/tic.c @@ -245,14 +245,13 @@ static void drawRectBorder(tic_machine* machine, s32 x, s32 y, s32 width, s32 he drawVLine(machine, x + width - 1, y, height, color); } -#define DRAW_TILE_BODY(index_expr) ({\ - y += sy; \ +#define DRAW_TILE_BODY(INDEX_EXPR) ({\ for(s32 py=sy; py < ey; py++, y++) \ { \ - s32 xx = x + sx; \ + s32 xx = x; \ for(s32 px=sx; px < ex; px++, xx++) \ { \ - u8 color = mapping[tic_tool_peek4(buffer, index_expr)]; \ + u8 color = mapping[tic_tool_peek4(buffer, INDEX_EXPR)]; \ if(color != 255) tic_tool_poke4(machine->memory.ram.vram.screen.data, y * TIC80_WIDTH + xx, color); \ } \ } \ @@ -282,6 +281,8 @@ static void drawTile(tic_machine* machine, const tic_tile* buffer, s32 x, s32 y, sy = machine->state.clip.t - y; if (sy < 0) sy = 0; ex = machine->state.clip.r - x; if (ex > TIC_SPRITESIZE) ex = TIC_SPRITESIZE; ey = machine->state.clip.b - y; if (ey > TIC_SPRITESIZE) ey = TIC_SPRITESIZE; + y += sy; + x += sx; switch (orientation) { case 0b100: DRAW_TILE_BODY(INDEX_XY(py, px)); break; case 0b110: DRAW_TILE_BODY(INDEX_XY(REVERT(py), px)); break; @@ -302,22 +303,15 @@ static void drawTile(tic_machine* machine, const tic_tile* buffer, s32 x, s32 y, for(s32 px=0; px < TIC_SPRITESIZE; px++, xx+=scale) { s32 i; - s32 ix, iy; - ix = orientation & 0b001 ? TIC_SPRITESIZE - px - 1: px; - iy = orientation & 0b010 ? TIC_SPRITESIZE - py - 1: py; + s32 ix = orientation & 0b001 ? TIC_SPRITESIZE - px - 1: px; + s32 iy = orientation & 0b010 ? TIC_SPRITESIZE - py - 1: py; if(orientation & 0b100) { i = ix * TIC_SPRITESIZE + iy; } else { i = iy * TIC_SPRITESIZE + ix; } u8 color = tic_tool_peek4(buffer, i); - if(mapping[color] != 255) { - if (scale == 1) { - setPixel(machine, xx, y, color); - } else { - drawRect(machine, xx, y, scale, scale, color); - } - } + if(mapping[color] != 255) drawRect(machine, xx, y, scale, scale, color); } } } From 96fe96dd0019c2c735225c7c5ff3aa75ab089268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Jahoda?= Date: Sun, 3 Dec 2017 22:39:22 +0100 Subject: [PATCH 4/4] Implement changes from overlap drawing. --- src/tic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tic.c b/src/tic.c index 19e66b1..5f03f15 100644 --- a/src/tic.c +++ b/src/tic.c @@ -155,7 +155,7 @@ static inline u8 mapColor(tic_mem* tic, u8 color) static void setPixelDma(tic_mem* tic, s32 x, s32 y, u8 color) { - tic_tool_poke4(tic->ram.vram.screen.data, y * TIC80_WIDTH + x, mapColor(tic, color)); + tic_tool_poke4(tic->ram.vram.screen.data, y * TIC80_WIDTH + x, color); } static inline u32* getOvrAddr(tic_mem* tic, s32 x, s32 y) @@ -170,7 +170,7 @@ static void setPixelOvr(tic_mem* tic, s32 x, s32 y, u8 color) { tic_machine* machine = (tic_machine*)tic; - *getOvrAddr(tic, x, y) = *(machine->state.ovr.palette + mapColor(tic, color)); + *getOvrAddr(tic, x, y) = *(machine->state.ovr.palette + color); } static u8 getPixelOvr(tic_mem* tic, s32 x, s32 y) @@ -198,7 +198,7 @@ static void setPixel(tic_machine* machine, s32 x, s32 y, u8 color) { if(x < machine->state.clip.l || y < machine->state.clip.t || x >= machine->state.clip.r || y >= machine->state.clip.b) return; - machine->state.setpix(&machine->memory, x, y, color); + machine->state.setpix(&machine->memory, x, y, mapColor(&machine->memory, color)); } static u8 getPixel(tic_machine* machine, s32 x, s32 y) @@ -252,7 +252,7 @@ static void drawRectBorder(tic_machine* machine, s32 x, s32 y, s32 width, s32 he for(s32 px=sx; px < ex; px++, xx++) \ { \ u8 color = mapping[tic_tool_peek4(buffer, INDEX_EXPR)]; \ - if(color != 255) tic_tool_poke4(machine->memory.ram.vram.screen.data, y * TIC80_WIDTH + xx, color); \ + if(color != 255) machine->state.setpix(&machine->memory, xx, y, color); \ } \ } \ })