Files
factorygame/util/atlas.c
2025-06-08 17:22:30 +02:00

133 lines
3.6 KiB
C

//
// 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);
}