// // Created by bruno on 1.6.2025. // #include "atlas.h" #include "util.h" SDL_Texture *atlasTexture; int tileIndex16 = 0, quadrantIndex16 = 0; int tileIndex32 = 0; int allocatedRectCount = 0; SDL_Rect allocatedRects[MAX_RECTS]; bool isIntersecting(SDL_Rect a) { for (int i = 0; i < allocatedRectCount; i++) { SDL_Rect b = allocatedRects[i]; if (SDL_HasIntersection(&a, &b)) { // printf("Rect intersection %d - X:%d, Y: %d, W: %d, H: %d with X:%d, Y: %d, W: %d, H: %d\n", // allocatedRectCount, a.x, a.y, a.w, a.h, b.x, b.y, b.w, b.h); return 1; } } return 0; } void storeRect(SDL_Rect rect) { if (isIntersecting(rect)) { printf("PROBLEM\n"); } if (allocatedRectCount < MAX_RECTS) { allocatedRects[allocatedRectCount++] = rect; } else { fprintf(stderr, "Error: atlas tileRect limit reached!\n"); } } SDL_Rect allocate_16x16(SDL_Texture *srcTexture, SDL_Renderer *renderer) { SDL_Texture *oldTarget = SDL_GetRenderTarget(renderer); SDL_SetRenderTarget(renderer, atlasTexture); SDL_Rect sourceRect = { 0, 0, QUADRANT_SIZE, QUADRANT_SIZE }; SDL_Rect destRect; while (1) { int tileX = tileIndex16 % ATLAS_TILES_PER_ROW; int tileY = tileIndex16 / ATLAS_TILES_PER_ROW; int dx = (quadrantIndex16 % 2) * QUADRANT_SIZE; int dy = (quadrantIndex16 / 2) * QUADRANT_SIZE; destRect.x = tileX * TILE_SIZE + dx; destRect.y = tileY * TILE_SIZE + dy; destRect.w = QUADRANT_SIZE; destRect.h = QUADRANT_SIZE; if (isIntersecting(destRect)) { tileIndex16 = tileIndex32; tileIndex32++; quadrantIndex16 = 0; continue; } else { break; } } SDL_RenderCopy(renderer, srcTexture, &sourceRect, &destRect); quadrantIndex16++; if (quadrantIndex16 >= 4) { tileIndex16 = tileIndex32; tileIndex32 += 1; quadrantIndex16 = 0; // Ensure 32x32 allocator skips this tile if (tileIndex32 <= tileIndex16) { tileIndex32 = tileIndex16 + 1; } } SDL_SetRenderTarget(renderer, oldTarget); storeRect(destRect); // printf("Rect X:%d, Y: %d, W: %d, H: %d\n", destRect.x, destRect.y, destRect.w, destRect.h); return destRect; } SDL_Rect allocate_32x32(SDL_Texture *srcTexture, SDL_Renderer *renderer) { SDL_Texture *oldTarget = SDL_GetRenderTarget(renderer); SDL_SetRenderTarget(renderer, atlasTexture); int tileX = tileIndex32 % ATLAS_TILES_PER_ROW; int tileY = tileIndex32 / ATLAS_TILES_PER_ROW; SDL_Rect destRect = { tileX * TILE_SIZE, tileY * TILE_SIZE, TILE_SIZE, TILE_SIZE }; SDL_RenderCopy(renderer, srcTexture, NULL, &destRect); tileIndex32++; SDL_SetRenderTarget(renderer, oldTarget); storeRect(destRect); // printf("Rect X:%d, Y: %d, W: %d, H: %d\n", destRect.x, destRect.y, destRect.w, destRect.h); return destRect; } void initAtlas(SDL_Renderer *renderer) { SDL_Texture *oldTarget = SDL_GetRenderTarget(renderer); atlasTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, ATLAS_SIZE, ATLAS_SIZE); // Clear atlas with transparent SDL_SetRenderTarget(renderer, atlasTexture); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); SDL_SetRenderTarget(renderer, oldTarget); }