Files
factorygame/tiles/belt.c
2025-06-10 21:59:51 +02:00

116 lines
4.5 KiB
C

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