116 lines
4.5 KiB
C
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);
|
|
}
|
|
} |