#include "level.h" #include "conf.h" #include "tile.h" #include "vec.h" #include "visual_data.h" #include #include static struct Level level; extern bopti_image_t bimg_tileset; static void level_free(void); void level_init(void) { level.data = NULL; level.visual_data = NULL; } void level_deinit(void) { level_free(); } void level_load(const struct LevelBin *b) { int i = b->width * b->height; level_free(); level.width = b->width; level.height = b->height; level.size = i; level.data = malloc(i); level.visual_data = malloc(i * sizeof(struct VisualData)); level.bin = b; while (i-- > 0) level.data[i] = b->data[i]; level_regen_visual_data(); } void level_reload(void) { level_load(level.bin); } void level_regen_visual_data(void) { const int tileset_width = bimg_tileset.width / TILE_SIZE; int y = level.height; while (y-- > 0) { int x = level.width; while (x-- > 0) { const int i = x + y * level.width; const int tile = level.data[i]; struct VisualData *const vd = &level.visual_data[i]; vd->x = x * TILE_SIZE; vd->y = y * TILE_SIZE; vd->img_x = tile % tileset_width * TILE_SIZE; vd->img_y = (int)(tile / tileset_width) * TILE_SIZE; vd->visible = tile != 0; } } } void level_draw(void) { int i = level.size; while (i-- > 0) { const struct VisualData *const vd = &level.visual_data[i]; if (vd->visible) { dsubimage(vd->x, vd->y, &bimg_tileset, vd->img_x, vd->img_y, TILE_SIZE, TILE_SIZE, 0); } } } int level_get(int x, int y) { if (x < 0 || y < 0 || x >= level.width || y >= level.height) return TILE_OOB; return level.data[x + y * level.width]; } int level_get_px(int x, int y) { return level_get(x / TILE_SIZE, y / TILE_SIZE); } struct Vec level_find(enum Tile t) { int i = level.size; while (i-- > 0 && level.data[i] != t) ; return (struct Vec){i % level.width, i / level.width}; } static void level_free(void) { if (level.data != NULL) { free(level.data); level.data = NULL; } if (level.visual_data != NULL) { free(level.visual_data); level.visual_data = NULL; } }