From febebf43e51f443ae07b84a6ea343b0b3a4ea682 Mon Sep 17 00:00:00 2001 From: KikooDX Date: Sun, 11 Apr 2021 01:45:40 +0200 Subject: [PATCH] optimisation: make drawing level faster No more framedrops. Nice. --- include/conf.h | 39 ++++++++++++++++++++------------------- include/level.h | 10 +++++++++- src/level/draw.c | 42 ++++++++++-------------------------------- src/level/load.c | 29 ++++++++++++++++++++++++++--- src/player/collide.c | 2 ++ src/player/init.c | 3 --- 6 files changed, 67 insertions(+), 58 deletions(-) diff --git a/include/conf.h b/include/conf.h index c400a74..1682c8a 100644 --- a/include/conf.h +++ b/include/conf.h @@ -2,22 +2,23 @@ /* Copyright (C) 2021 KikooDX */ #pragma once -#define TILE_WIDTH 16 -#define TILE_HEIGHT 16 -#define TARGET_FPS 30 -#define TARGET_UPS 60 -#define ACC_GND 0.1 -#define ACC_AIR 0.025 -#define MAX_HSPD 3.0 -#define FRC_GND (ACC_GND / MAX_HSPD) -#define FRC_AIR (ACC_AIR / MAX_HSPD) -#define AIR_RES 0.02 -#define GRAVITY 0.2 -#define JUMP_SPD -4.0 -#define AIR_JMP_SPD -3.0 -#define JUMP_BUFFER 10 -#define JUMP_GRACE 10 -#define AIR_JUMPS 3 -#define BURST_BOOST 0.5 -#define V_TRANS_SPD (1.0 / 15.0) -#define H_TRANS_SPD (1.0 / 20.0) +#define TILE_WIDTH 16 +#define TILE_HEIGHT 16 +#define TILESET_WIDTH 16 +#define TARGET_FPS 30 +#define TARGET_UPS 60 +#define ACC_GND 0.1 +#define ACC_AIR 0.025 +#define MAX_HSPD 3.0 +#define FRC_GND (ACC_GND / MAX_HSPD) +#define FRC_AIR (ACC_AIR / MAX_HSPD) +#define AIR_RES 0.02 +#define GRAVITY 0.2 +#define JUMP_SPD -4.0 +#define AIR_JMP_SPD -3.0 +#define JUMP_BUFFER 10 +#define JUMP_GRACE 10 +#define AIR_JUMPS 3 +#define BURST_BOOST 0.5 +#define V_TRANS_SPD (1.0 / 15.0) +#define H_TRANS_SPD (1.0 / 20.0) diff --git a/include/level.h b/include/level.h index 2545919..7018f5b 100644 --- a/include/level.h +++ b/include/level.h @@ -9,9 +9,17 @@ typedef unsigned int Tile; +struct VisualTile { + int visible; + int x; + int y; + int texture_x; + int texture_y; +}; + struct Level { Tile data[LEVEL_WIDTH * LEVEL_HEIGHT]; - int autotiling[LEVEL_WIDTH * LEVEL_HEIGHT]; + struct VisualTile visual_data[LEVEL_WIDTH * LEVEL_HEIGHT]; int width; int height; int gold; diff --git a/src/level/draw.c b/src/level/draw.c index 659af93..52f250a 100644 --- a/src/level/draw.c +++ b/src/level/draw.c @@ -11,39 +11,17 @@ extern const bopti_image_t bimg_tileset; void level_draw(void) { - int x; - int y; - const int tileset_width = bimg_tileset.width / TILE_WIDTH; + int i; - y = level.height; - while (y-- > 0) { - const int draw_y = y * TILE_HEIGHT; - x = level.width; - while (x-- > 0) { - const int draw_x = x * TILE_WIDTH; - const int tile_index = x + y * level.width; - const Tile tile = level.data[tile_index]; - switch (tile) { - case TILE_VOID: - break; - case TILE_SOLID: { - const int autotile = - level.autotiling[tile_index]; - dsubimage(draw_x, draw_y, &bimg_tileset, - autotile, TILE_HEIGHT, - TILE_WIDTH, TILE_HEIGHT, - DIMAGE_NOCLIP); - } break; - default: - dsubimage(draw_x, draw_y, &bimg_tileset, - (int)(tile % tileset_width) * - TILE_WIDTH, - (int)(tile / tileset_width) * - TILE_HEIGHT, - TILE_WIDTH, TILE_HEIGHT, - DIMAGE_NOCLIP); - break; - } + i = level.height * level.width; + while (i-- > 0) { + const struct VisualTile *visual_tile = + &level.visual_data[i]; + if (visual_tile->visible) { + dsubimage(visual_tile->x, visual_tile->y, + &bimg_tileset, visual_tile->texture_x, + visual_tile->texture_y, TILE_WIDTH, + TILE_HEIGHT, DIMAGE_NOCLIP); } } } diff --git a/src/level/load.c b/src/level/load.c index 7176ed3..b9e1436 100644 --- a/src/level/load.c +++ b/src/level/load.c @@ -93,13 +93,36 @@ void level_load(void) /* set level id for display */ level.id = level_id; - /* compute autotiling */ + /* compute visuals */ y = level.height; + i = 0; while (y-- > 0) { x = level.width; while (x-- > 0) { - level.autotiling[x + y * level.width] = - autotile_value(x, y) * TILE_WIDTH; + tile = level.data[x + y * level.width]; + struct VisualTile visual_data; + visual_data.x = x * TILE_WIDTH; + visual_data.y = y * TILE_HEIGHT; + visual_data.visible = tile != TILE_START; + if (tile == TILE_SOLID) { + const int autotile = + autotile_value(x, y); + visual_data.texture_x = + autotile * TILE_WIDTH; + visual_data.texture_y = TILE_HEIGHT; + visual_data.visible = autotile != 15; + } else if (tile != TILE_VOID) { + visual_data.texture_x = + (int)(tile % TILESET_WIDTH) * + TILE_WIDTH; + visual_data.texture_y = + (int)(tile / TILESET_WIDTH) * + TILE_HEIGHT; + } else { + visual_data.visible = 0; + } + level.visual_data[x + y * level.width] = + visual_data; } } diff --git a/src/player/collide.c b/src/player/collide.c index 857940e..d9cc48c 100644 --- a/src/player/collide.c +++ b/src/player/collide.c @@ -84,6 +84,8 @@ static int collide_sub_single(int x, int y, Tile sub, Tile rep) /* replace tile */ level.data[tile_index] = rep; + if (rep == TILE_VOID) + level.visual_data[tile_index].visible = 0; /* spawn animations */ switch (sub) { diff --git a/src/player/init.c b/src/player/init.c index 78e1ff6..4d924f6 100644 --- a/src/player/init.c +++ b/src/player/init.c @@ -31,9 +31,6 @@ struct Player player_init(void) while (y-- > 0) { if (level.data[x + y * level.width] == TILE_START) { - /* erase start tile */ - level.data[x + y * level.width] = - TILE_VOID; /* set player position */ player.x = x * TILE_WIDTH +