mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Same Game: more efficient tile_redraw
I've rewritten tile_redraw to reduce the number of calls to draw_rect(). Before, it would generally make five calls to draw_rect() when drawing a tile. Now it makes at most three, and usually two. That's one draw_rect() for each colour that appears in the tile, which is as good as it can get. This reduces the time to draw a large puzzle by about 35% on Firefox 102. This is of significance to me because CanvasRenderingContext2D on my test KaiOS device seems to have a limit on the number of fill() and fillRect() calls that it will tolerate in a short time. This means that if you issue more than 1024 fillRect() calls in rapid succession, the later ones are simply ignored. Same Game's largest preset called draw_rect() so much that it hit this limit. That meant that the right-hand side of the grid didn't get properly drawn when starting a new game. Now that it is less profligate with draw_rect() it fits comfortably within the limit and I get to see the entire grid.
This commit is contained in:
33
samegame.c
33
samegame.c
@ -1471,6 +1471,7 @@ static void tile_redraw(drawing *dr, game_drawstate *ds,
|
|||||||
int tile, int bgcolour)
|
int tile, int bgcolour)
|
||||||
{
|
{
|
||||||
int outer = bgcolour, inner = outer, col = tile & TILE_COLMASK;
|
int outer = bgcolour, inner = outer, col = tile & TILE_COLMASK;
|
||||||
|
int tile_w, tile_h, outer_w, outer_h;
|
||||||
|
|
||||||
if (col) {
|
if (col) {
|
||||||
if (tile & TILE_IMPOSSIBLE) {
|
if (tile & TILE_IMPOSSIBLE) {
|
||||||
@ -1483,19 +1484,25 @@ static void tile_redraw(drawing *dr, game_drawstate *ds,
|
|||||||
outer = inner = col;
|
outer = inner = col;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
draw_rect(dr, COORD(x), COORD(y), TILE_INNER, TILE_INNER, outer);
|
tile_w = dright ? TILE_SIZE : TILE_INNER;
|
||||||
draw_rect(dr, COORD(x)+TILE_INNER/4, COORD(y)+TILE_INNER/4,
|
tile_h = dbelow ? TILE_SIZE : TILE_INNER;
|
||||||
TILE_INNER/2, TILE_INNER/2, inner);
|
outer_w = (tile & TILE_JOINRIGHT) ? tile_w : TILE_INNER;
|
||||||
|
outer_h = (tile & TILE_JOINDOWN) ? tile_h : TILE_INNER;
|
||||||
if (dright)
|
/* Draw the background if any of it will be visible. */
|
||||||
draw_rect(dr, COORD(x)+TILE_INNER, COORD(y), TILE_GAP, TILE_INNER,
|
if (outer_w != tile_w || outer_h != tile_h || outer == bgcolour)
|
||||||
(tile & TILE_JOINRIGHT) ? outer : bgcolour);
|
draw_rect(dr, COORD(x), COORD(y), tile_w, tile_h, bgcolour);
|
||||||
if (dbelow)
|
/* Draw the piece. */
|
||||||
draw_rect(dr, COORD(x), COORD(y)+TILE_INNER, TILE_INNER, TILE_GAP,
|
if (outer != bgcolour)
|
||||||
(tile & TILE_JOINDOWN) ? outer : bgcolour);
|
draw_rect(dr, COORD(x), COORD(y), outer_w, outer_h, outer);
|
||||||
if (dright && dbelow)
|
if (inner != outer)
|
||||||
draw_rect(dr, COORD(x)+TILE_INNER, COORD(y)+TILE_INNER, TILE_GAP, TILE_GAP,
|
draw_rect(dr, COORD(x)+TILE_INNER/4, COORD(y)+TILE_INNER/4,
|
||||||
(tile & TILE_JOINDIAG) ? outer : bgcolour);
|
TILE_INNER/2, TILE_INNER/2, inner);
|
||||||
|
/* Reset bottom-right corner if necessary. */
|
||||||
|
if ((tile & (TILE_JOINRIGHT | TILE_JOINDOWN | TILE_JOINDIAG)) ==
|
||||||
|
(TILE_JOINRIGHT | TILE_JOINDOWN) && outer != bgcolour &&
|
||||||
|
TILE_GAP != 0)
|
||||||
|
draw_rect(dr, COORD(x)+TILE_INNER, COORD(y)+TILE_INNER,
|
||||||
|
TILE_GAP, TILE_GAP, bgcolour);
|
||||||
|
|
||||||
if (tile & TILE_HASSEL) {
|
if (tile & TILE_HASSEL) {
|
||||||
int sx = COORD(x)+2, sy = COORD(y)+2, ssz = TILE_INNER-5;
|
int sx = COORD(x)+2, sy = COORD(y)+2, ssz = TILE_INNER-5;
|
||||||
|
Reference in New Issue
Block a user