Testing
This commit is contained in:
@@ -33,7 +33,7 @@ void storeRect(SDL_Rect rect) {
|
||||
if (allocatedRectCount < MAX_RECTS) {
|
||||
allocatedRects[allocatedRectCount++] = rect;
|
||||
} else {
|
||||
fprintf(stderr, "Error: atlas rect limit reached!\n");
|
||||
fprintf(stderr, "Error: atlas tileRect limit reached!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -106,7 +106,7 @@ void audio_callback(void *userdata, Uint8 *stream, int len) {
|
||||
|
||||
float gainL = 1;
|
||||
float gainR = 1;
|
||||
float targetAmp = (voice->volume / 255.0f);
|
||||
float targetAmp = (voice->volume / 255.0f) / 2;
|
||||
if (v < NUM_SYNTH_VOICES - MIDI_VOICES) {
|
||||
float distanceAtten = 1.0f - fminf(fabsf(dx) / audio->maxPanDistance, 1.0f);
|
||||
targetAmp *= distanceAtten;
|
||||
|
128
util/pathfinding.c
Normal file
128
util/pathfinding.c
Normal file
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// Created by bruno on 7.6.2025.
|
||||
//
|
||||
|
||||
#include "pathfinding.h"
|
||||
|
||||
uint32_t globalPathfindingVersion = 1;
|
||||
|
||||
Node openList[MAX_OPEN_NODES];
|
||||
int openCount = 0;
|
||||
|
||||
|
||||
void clear_pathfind_data() {
|
||||
for (int y = 0; y < MAP_HEIGHT; ++y)
|
||||
for (int x = 0; x < MAP_WIDTH; ++x)
|
||||
tileMap[y][x].pathFind = (PathFindDat) {0};
|
||||
}
|
||||
|
||||
int heuristic(MiniRect a, MiniRect b) {
|
||||
return abs(a.x - b.x) + abs(a.y - b.y);
|
||||
}
|
||||
|
||||
|
||||
void add_to_open(MiniRect pos, int fCost) {
|
||||
if (openCount < MAX_OPEN_NODES)
|
||||
openList[openCount++] = (Node) {pos.x, pos.y, fCost};
|
||||
}
|
||||
|
||||
Node pop_best_node() {
|
||||
int bestIdx = 0;
|
||||
for (int i = 1; i < openCount; ++i) {
|
||||
if (openList[i].fCost < openList[bestIdx].fCost)
|
||||
bestIdx = i;
|
||||
}
|
||||
|
||||
Node best = openList[bestIdx];
|
||||
openList[bestIdx] = openList[--openCount];
|
||||
return best;
|
||||
}
|
||||
|
||||
bool find_path(MiniRect start, MiniRect end) {
|
||||
clear_pathfind_data();
|
||||
openCount = 0;
|
||||
|
||||
Tile *startT = &tileMap[start.y][start.x];
|
||||
startT->pathFind.gCost = 0;
|
||||
startT->pathFind.hCost = heuristic(start, end);
|
||||
startT->pathFind.open = true;
|
||||
|
||||
add_to_open(start, startT->pathFind.gCost + startT->pathFind.hCost);
|
||||
|
||||
const int dirs[4][2] = {
|
||||
{0, -1},
|
||||
{1, 0},
|
||||
{0, 1},
|
||||
{-1, 0}
|
||||
};
|
||||
|
||||
while (openCount > 0) {
|
||||
Node current = pop_best_node();
|
||||
PathFindDat *currentPath = &tileMap[current.pos.y][current.pos.x].pathFind;
|
||||
currentPath->open = false;
|
||||
currentPath->closed = true;
|
||||
|
||||
if (memcmp(¤t.pos, &end, sizeof(MiniRect)) == 0) {
|
||||
return true; // Path found!
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
MiniRect n = {current.pos.x + dirs[i][0], current.pos.y + dirs[i][1]};
|
||||
|
||||
if (!isWalkable(n)) continue;
|
||||
|
||||
PathFindDat *neighbor = &tileMap[n.y][n.x].pathFind;
|
||||
|
||||
if (neighbor->closed) continue;
|
||||
|
||||
int tentativeG = currentPath->gCost + 1;
|
||||
|
||||
if (!neighbor->open || tentativeG < neighbor->gCost) {
|
||||
neighbor->gCost = tentativeG;
|
||||
neighbor->hCost = heuristic(n, end);
|
||||
neighbor->parent = currentPath;
|
||||
|
||||
if (!neighbor->open) {
|
||||
neighbor->open = true;
|
||||
add_to_open(n, neighbor->gCost + neighbor->hCost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false; // No path found
|
||||
}
|
||||
|
||||
Path reconstruct_path(MiniRect end) {
|
||||
Path path = { .length = 0 };
|
||||
|
||||
PathFindDat* current = &tileMap[end.y][end.x].pathFind;
|
||||
|
||||
// Walk back through the parent pointers
|
||||
while (current != NULL) {
|
||||
// Find the tile coordinates for the current node
|
||||
for (int y = 0; y < MAP_HEIGHT; ++y) {
|
||||
for (int x = 0; x < MAP_WIDTH; ++x) {
|
||||
if (&tileMap[y][x].pathFind == current) {
|
||||
if (path.length < MAX_OPEN_NODES) {
|
||||
path.steps[path.length++] = (MiniRect){ x, y };
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
found:
|
||||
current = current->parent;
|
||||
}
|
||||
|
||||
// Reverse the path to go from start to end
|
||||
for (int i = 0; i < path.length / 2; ++i) {
|
||||
MiniRect tmp = path.steps[i];
|
||||
path.steps[i] = path.steps[path.length - i - 1];
|
||||
path.steps[path.length - i - 1] = tmp;
|
||||
}
|
||||
path.stepIndex = 0;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
42
util/pathfinding.h
Normal file
42
util/pathfinding.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// Created by bruno on 7.6.2025.
|
||||
//
|
||||
|
||||
#ifndef FACTORYGAME_PATHFINDING_H
|
||||
#define FACTORYGAME_PATHFINDING_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../tiles/tile.h"
|
||||
|
||||
//extern uint32_t globalPathfindingVersion;
|
||||
//#define MAX_OPEN_NODES (MAP_WIDTH * MAP_HEIGHT)
|
||||
#define MAX_OPEN_NODES 100
|
||||
|
||||
typedef struct Node {
|
||||
MiniRect pos;
|
||||
int fCost;
|
||||
} Node;
|
||||
|
||||
typedef struct {
|
||||
MiniRect steps[MAX_OPEN_NODES];
|
||||
int stepIndex;
|
||||
int length;
|
||||
} Path;
|
||||
|
||||
|
||||
extern Node openList[MAX_OPEN_NODES];
|
||||
extern int openCount;
|
||||
|
||||
int heuristic(MiniRect a, MiniRect b);
|
||||
|
||||
Path reconstruct_path(MiniRect end);
|
||||
|
||||
bool find_path(MiniRect start, MiniRect end);
|
||||
|
||||
Node pop_best_node();
|
||||
|
||||
void add_to_open(MiniRect pos, int fCost);
|
||||
|
||||
void clear_pathfind_data();
|
||||
|
||||
#endif //FACTORYGAME_PATHFINDING_H
|
109
util/util.c
109
util/util.c
@@ -4,6 +4,8 @@
|
||||
|
||||
#include <dirent.h>
|
||||
#include "util.h"
|
||||
#include "../tiles/tile.h"
|
||||
#include "font.h"
|
||||
//#include "font.h"
|
||||
|
||||
|
||||
@@ -132,7 +134,7 @@ void renderBar(SDL_Renderer *renderer,
|
||||
char barString[20];
|
||||
sprintf(barString, "%d/%d", currentValue, maxValue);
|
||||
|
||||
//renderText(mainRenderer, fonts[3], barString, width / 2, margin);
|
||||
renderText(mainRenderer, fonts[3], barString, width / 2, margin);
|
||||
}
|
||||
|
||||
int cmpstringp(const void *p1, const void *p2) {
|
||||
@@ -178,4 +180,109 @@ void iterateSortedDir(const char *path, DirEntryCallback callback, SDL_Renderer
|
||||
}
|
||||
free(names);
|
||||
}
|
||||
}
|
||||
|
||||
bool checkCollision(SDL_Rect a, SDL_Rect b) {
|
||||
//The sides of the rectangles
|
||||
int leftA, leftB;
|
||||
int rightA, rightB;
|
||||
int topA, topB;
|
||||
int bottomA, bottomB;
|
||||
|
||||
//Calculate the sides of tileRect A
|
||||
leftA = a.x;
|
||||
rightA = a.x + a.w;
|
||||
topA = a.y;
|
||||
bottomA = a.y + a.h;
|
||||
|
||||
//Calculate the sides of tileRect B
|
||||
leftB = b.x;
|
||||
rightB = b.x + b.w;
|
||||
topB = b.y;
|
||||
bottomB = b.y + b.h;
|
||||
|
||||
//If any of the sides from A are outside of B
|
||||
if (bottomA <= topB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (topA >= bottomB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rightA <= leftB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (leftA >= rightB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//If none of the sides from A are outside B
|
||||
return true;
|
||||
}
|
||||
|
||||
bool canMoveTo(SDL_Rect newRect) {
|
||||
// Round down to get all tiles the rect overlaps
|
||||
int left = newRect.x / TILE_SIZE;
|
||||
int right = (newRect.x + newRect.w - 1) / TILE_SIZE;
|
||||
int top = newRect.y / TILE_SIZE;
|
||||
int bottom = (newRect.y + newRect.h - 1) / TILE_SIZE;
|
||||
|
||||
for (int tx = left; tx <= right; ++tx) {
|
||||
for (int ty = top; ty <= bottom; ++ty) {
|
||||
MiniRect tile = { tx, ty };
|
||||
if (!isWalkable(tile)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool canMoveWithRadius(SDL_Rect centerRect) {
|
||||
// 16px radius — create a square bounding box around center
|
||||
int radius = 16;
|
||||
|
||||
int left = (centerRect.x - radius) / TILE_SIZE;
|
||||
int right = (centerRect.x + radius - 1) / TILE_SIZE;
|
||||
int top = (centerRect.y - radius) / TILE_SIZE;
|
||||
int bottom = (centerRect.y + radius - 1) / TILE_SIZE;
|
||||
|
||||
int x, y;
|
||||
for (x = left; x <= right; x++) {
|
||||
for (y = top; y <= bottom; y++) {
|
||||
MiniRect tile;
|
||||
tile.x = x;
|
||||
tile.y = y;
|
||||
|
||||
if (!isWalkable(tile)) {
|
||||
// Get pixel bounds of tile
|
||||
int tileLeft = x * TILE_SIZE;
|
||||
int tileRight = tileLeft + TILE_SIZE;
|
||||
int tileTop = y * TILE_SIZE;
|
||||
int tileBottom = tileTop + TILE_SIZE;
|
||||
|
||||
// Bounding box of the player
|
||||
int playerLeft = centerRect.x - radius;
|
||||
int playerRight = centerRect.x + radius;
|
||||
int playerTop = centerRect.y - radius;
|
||||
int playerBottom = centerRect.y + radius;
|
||||
|
||||
// AABB collision check
|
||||
if (playerRight > tileLeft && playerLeft < tileRight &&
|
||||
playerBottom > tileTop && playerTop < tileBottom) {
|
||||
return 0; // Collision
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1; // No collisions
|
||||
}
|
||||
|
||||
int compareStrings(const void *a, const void *b) {
|
||||
const char *strA = *(const char **) a;
|
||||
const char *strB = *(const char **) b;
|
||||
return strcmp(strA, strB);
|
||||
}
|
10
util/util.h
10
util/util.h
@@ -72,4 +72,12 @@ void renderBar(SDL_Renderer *renderer,
|
||||
int maxValue, int currentValue,
|
||||
SDL_Color barColor, int margin);
|
||||
|
||||
#endif //FACTORYGAME_UTIL_H
|
||||
bool checkCollision(SDL_Rect a, SDL_Rect b);
|
||||
|
||||
int compareStrings(const void *a, const void *b);
|
||||
|
||||
bool canMoveTo(SDL_Rect newRect);
|
||||
|
||||
bool canMoveWithRadius(SDL_Rect centerRect);
|
||||
|
||||
#endif //FACTORYGAME_UTIL_H
|
Reference in New Issue
Block a user