/** * Copyright (c) 2024 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "drawmap.h" #include "assert/assert.h" #include "display/symbol.h" void drawMap( const map_t *map, const uint16_t cameraX, const uint16_t cameraY, const uint16_t drawX, const uint16_t drawY, const uint16_t drawWidth, const uint16_t drawHeight ) { assertNotNull(map, "Map cannot be NULL."); assertTrue(drawX < FRAME_WIDTH, "Map is too far right."); assertTrue(drawY < FRAME_HEIGHT, "Map is too far down."); assertTrue(drawWidth > 0, "Map is too narrow."); assertTrue(drawHeight > 0, "Map is too short."); assertTrue(drawX + drawWidth <= FRAME_WIDTH, "Map is too wide."); assertTrue(drawY + drawHeight <= FRAME_HEIGHT, "Map is too tall."); entity_t *ent; tile_t tile; uint32_t i; char_t *bufferDest; uint8_t *colorDest; // If the size of the map's smaller than the frame, center it, otherwise use // the cameraPosition as the center point. int16_t offsetX = 0, offsetY = 0; if(map->width < drawWidth) { offsetX = (drawWidth - map->width) / 2; } else { // Clamp to map bounds if(cameraX < drawWidth / 2) { offsetX = 0; } else if(cameraX >= map->width - (drawWidth / 2)) { offsetX = -(map->width - drawWidth); } else { offsetX = -(cameraX - (drawWidth / 2)); } } if(map->height < drawHeight) { offsetY = (drawHeight - map->height) / 2; } else { // Clamp to map bounds if(cameraY < drawHeight / 2) { offsetY = 0; } else if(cameraY >= map->height - (drawHeight / 2)) { offsetY = -(map->height - drawHeight); } else { offsetY = -(cameraY - (drawHeight / 2)); } } // Draw the map i = 0; for(uint16_t y = 0; y < drawHeight; y++) { bufferDest = &FRAME_BUFFER[(drawY + y) * FRAME_WIDTH + drawX]; colorDest = &FRAME_COLOR[(drawY + y) * FRAME_WIDTH + drawX]; for(uint16_t x = 0; x < drawWidth; x++) { if(x < offsetX || y < offsetY || x >= map->width + offsetX || y >= map->height + offsetY) { colorDest[x] = COLOR_BLACK; bufferDest[x] = ' '; continue; } // Entity? ent = mapEntityGetByPosition(map, x - offsetX, y - offsetY); if(ent != NULL) { colorDest[x] = symbolGetColorByEntity(ent); bufferDest[x] = symbolGetCharByEntity(ent); continue; } // Tile? tile = mapTileGetByPosition(map, x - offsetX, y - offsetY, 0); colorDest[x] = symbolGetColorByTile(tile); bufferDest[x] = symbolGetCharByTile(tile); } } }