#include "level.h" #include "sys.h" #include #include #include #include level_t load_level(const char *dir, const char *filename, i32 width, i32 height) { assert(filename); assert(width); assert(height); level_t level = {0}; char path[512] = {0}; snprintf(path, 512, "%s/%s", (dir ? dir : "."), filename); u8 *data = (u8 *)read_entire_file(path); if (!data) { info("failed to read \"%s\"", path); return level; } i32 rows = 0, col = 0, cols = 0; for (u8 *c = data; *c; c++) { if (isdigit(*c)) { col++; } else if (*c == '\n') { if (cols && col != cols) { info("row %d, columns differ (previous %d)", rows, cols); free(data); return level; } rows++; cols = col; col = 0; } } if (!rows) { info("invalid rows number"); return level; } if (!cols) { info("invalid columns number"); return level; } u8 *tiles = malloc(sizeof(u8) * rows * cols); i32 i = 0; for (u8 *c = data; *c; c++) if (isdigit(*c)) tiles[i++] = *c - '0'; level = init_level(tiles, rows, cols, width, height); free(tiles); free(data); info("level \"%s\" loaded successfully", path); return level; } level_t init_level(u8 *tiles, i32 rows, i32 cols, i32 width, i32 height) { assert(tiles); level_t level = {0}; level.rows = rows; level.cols = cols; f32 tile_width = width / cols; f32 tile_height = height / rows; v2 size = {tile_width, tile_height}; for (i32 i = 0; i < rows * cols; i++) if (tiles[i]) level.count++; level.tiles = malloc(sizeof(object_t) * level.count); i32 i = 0; for (i32 row = 0; row < rows; row++) { for (i32 col = 0; col < cols; col++) { u8 *tile = tiles + col + row * cols; if (!*tile) continue; object_t obj = {0}; obj.pos = (v2){tile_width * col, tile_height * row}; obj.size = size; obj.texture = get_texture_id("solid"); if (*tile == 1) { obj.color = (v3){0.8f, 0.8f, 0.7f}; obj.solid = 1; } else if (*tile > 1) { v3 color = {1.0f, 1.0f, 1.0f}; switch (*tile) { case 2: color = (v3){0.2f, 0.6f, 1.0f}; break; case 3: color = (v3){0.0f, 0.7f, 0.0f}; break; case 4: color = (v3){0.8f, 0.8f, 0.4f}; break; case 5: color = (v3){1.0f, 0.5f, 0.0f}; break; } obj.color = color; obj.texture = get_texture_id("block"); } level.tiles[i++] = obj; } } return level; } void clear_level(level_t *level) { free(level->tiles); level->tiles = 0; level->rows = 0; level->cols = 0; } void render_level(sprite_renderer_t renderer, level_t level) { for (i32 i = 0; i < level.count; i++) if (!level.tiles[i].destroyed) render_object(renderer, level.tiles[i]); } i32 level_is_completed(level_t level) { for (i32 i = 0; i < level.count; i++) if (!level.tiles[i].solid && !level.tiles[i].destroyed) return 0; return 1; }