// // Created by bruno on 4/24/25. // #include "belt.h" #include "../util/util.h" #include "tile.h" #include "../player/player.h" #include "../items/item.h" #include "../util/atlas.h" #include "../util/font.h" void generateBeltFrames(SDL_Renderer *renderer) { SDL_Texture *baseTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, TILE_SIZE, TILE_SIZE); SDL_Texture *oldTarget = SDL_GetRenderTarget(renderer); SDL_SetRenderTarget(renderer, baseTexture); SDL_RenderCopy(renderer, atlasTexture, &TileRegistry[TYPE_BELT].animation.atlasRects[ORIENT_LEFT][0], NULL); const int frameCount = TILE_SIZE; // 32 frames, 1px per frame = full seamless loop for (OrientDirection dir = ORIENT_LEFT_DOWN; dir < ORIENT_DIRECTION_COUNT; dir++) { double angle = 0.0; bool isHorizontal = true; bool reverse = false; switch (dir) { case ORIENT_LEFT: angle = 0; isHorizontal = true; reverse = false; break; case ORIENT_UP: angle = 90; isHorizontal = false; reverse = false; break; case ORIENT_RIGHT: angle = 180; isHorizontal = true; reverse = true; break; case ORIENT_DOWN: angle = 270; isHorizontal = false; reverse = true; break; default: continue; // skip diagonals or unsupported directions } // Step 1: Rotate the tile once SDL_Texture *rotated = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, TILE_SIZE, TILE_SIZE); SDL_SetTextureBlendMode(rotated, SDL_BLENDMODE_BLEND); SDL_SetRenderTarget(renderer, rotated); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); SDL_Rect full = {0, 0, TILE_SIZE, TILE_SIZE}; SDL_RenderCopyEx(renderer, baseTexture, NULL, &full, angle, NULL, SDL_FLIP_NONE); // Step 2: For each frame, render 2 rotated tiles with wrapping offset for (int f = 0; f < frameCount; f++) { SDL_Texture *frame = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, TILE_SIZE, TILE_SIZE); SDL_SetTextureBlendMode(frame, SDL_BLENDMODE_BLEND); SDL_SetRenderTarget(renderer, frame); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); int offset = reverse ? (TILE_SIZE - f) % TILE_SIZE : f; SDL_Rect dst1, dst2; if (isHorizontal) { dst1 = (SDL_Rect) {-offset, 0, TILE_SIZE, TILE_SIZE}; dst2 = (SDL_Rect) {TILE_SIZE - offset, 0, TILE_SIZE, TILE_SIZE}; } else { dst1 = (SDL_Rect) {0, -offset, TILE_SIZE, TILE_SIZE}; dst2 = (SDL_Rect) {0, TILE_SIZE - offset, TILE_SIZE, TILE_SIZE}; } SDL_RenderCopy(renderer, rotated, NULL, &dst1); SDL_RenderCopy(renderer, rotated, NULL, &dst2); TileRegistry[TYPE_BELT].animation.atlasRects[dir][f] = allocate_32x32(frame, renderer); } SDL_DestroyTexture(rotated); TileRegistry[TYPE_BELT].animation.frameCount = frameCount; TileRegistry[TYPE_BELT].animation.divisor = 1; } SDL_DestroyTexture(baseTexture); SDL_SetRenderTarget(renderer, oldTarget); } void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Rect playerRect, SDL_Renderer *renderer) { int px = x * TILE_SIZE; int py = y * TILE_SIZE; SDL_Rect dst = {px, py, w, h}; adjustRect(&dst, playerRect); SDL_RenderCopy(renderer, atlasTexture, &TileRegistry[TYPE_BELT].animation.atlasRects[dir][ (animationStep / TileRegistry[TYPE_BELT].animation.divisor) % TileRegistry[TYPE_BELT].animation.frameCount], &dst); if (tileMap[y][x].health < TileRegistry[TYPE_BELT].maxHealth) { char healthStr[12]; snprintf(healthStr, 12, "%d/%d", tileMap[y][x].health, TileRegistry[tileMap[y][x].type].maxHealth); renderText(renderer, fonts[3], healthStr, dst.x, dst.y); } }