Some more hopefully working progress
@@ -40,4 +40,4 @@ add_custom_target(copy_assets ALL
|
|||||||
add_dependencies(factorygame copy_assets)
|
add_dependencies(factorygame copy_assets)
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries(factorygame SDL2 SDL2_ttf SDL2_image SDL2_gfx SDL2_mixer SDL2_net m)
|
target_link_libraries(factorygame SDL2 SDL2_ttf SDL2_image m)
|
Before Width: | Height: | Size: 517 B |
Before Width: | Height: | Size: 566 B |
Before Width: | Height: | Size: 516 B |
Before Width: | Height: | Size: 513 B |
Before Width: | Height: | Size: 592 B |
Before Width: | Height: | Size: 492 B |
Before Width: | Height: | Size: 526 B |
Before Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 546 B |
Before Width: | Height: | Size: 120 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 202 B After Width: | Height: | Size: 202 B |
227
items/item.c
@@ -11,7 +11,7 @@ Item ItemRegistry[ITEMREGISTRY_SIZE];
|
|||||||
|
|
||||||
uint16_t itemRegistryIndex = 0;
|
uint16_t itemRegistryIndex = 0;
|
||||||
|
|
||||||
float speed = 0.002f; // fraction of tile per tick
|
double speed = 1.0f / TILE_SIZE; // fraction of tile per tick
|
||||||
|
|
||||||
void updateItems() {
|
void updateItems() {
|
||||||
const int dirDx[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
|
const int dirDx[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
|
||||||
@@ -29,70 +29,66 @@ void updateItems() {
|
|||||||
bool vert = (dir == ORIENT_UP || dir == ORIENT_DOWN);
|
bool vert = (dir == ORIENT_UP || dir == ORIENT_DOWN);
|
||||||
|
|
||||||
for (uint8_t lane = 0; lane < 2; lane++) {
|
for (uint8_t lane = 0; lane < 2; lane++) {
|
||||||
for (uint8_t slot = 0; slot < 2; slot++) {
|
ItemOnBelt *itm = &t->items[lane];
|
||||||
ItemOnBelt *itm = &t->items[lane][slot];
|
if (itm->type == 0) continue;
|
||||||
if (!itm->active) continue;
|
|
||||||
|
|
||||||
// 1) Advance
|
// 1) Advance
|
||||||
itm->offset += speed;
|
itm->offset += speed;
|
||||||
|
|
||||||
// 2) Time to hop?
|
// 2) Time to hop?
|
||||||
if (itm->offset >= 0.5f) {
|
if (itm->offset >= 0.5f) {
|
||||||
itm->offset -= 1.0f;
|
itm->offset -= 1.0f;
|
||||||
|
|
||||||
// target coords
|
// target coords
|
||||||
int nx = x + dirDx[dir];
|
int nx = x + dirDx[dir];
|
||||||
int ny = y + dirDy[dir];
|
int ny = y + dirDy[dir];
|
||||||
|
|
||||||
// bounds & belt?
|
// bounds & belt?
|
||||||
if (nx < 0 || nx >= MAP_WIDTH || ny < 0 || ny >= MAP_HEIGHT) {
|
if (nx < 0 || nx >= MAP_WIDTH || ny < 0 || ny >= MAP_HEIGHT) {
|
||||||
itm->active = false;
|
//itm->type = 0;
|
||||||
continue;
|
itm->offset += 1.0f - speed;
|
||||||
}
|
continue;
|
||||||
Tile *next = &tileMap[ny][nx];
|
}
|
||||||
if (next->type != TYPE_BELT) {
|
Tile *next = &tileMap[ny][nx];
|
||||||
itm->active = false;
|
if (next->type != TYPE_BELT) {
|
||||||
continue;
|
//itm->type = 0;
|
||||||
}
|
itm->offset += 1.0f - speed;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Decide new lane
|
// Decide new lane
|
||||||
int newLane = lane;
|
int newLane = lane;
|
||||||
int newDir = next->direction;
|
int newDir = next->direction;
|
||||||
bool nH = (newDir == ORIENT_LEFT || newDir == ORIENT_RIGHT);
|
bool nH = (newDir == ORIENT_LEFT || newDir == ORIENT_RIGHT);
|
||||||
bool nV = (newDir == ORIENT_UP || newDir == ORIENT_DOWN);
|
bool nV = (newDir == ORIENT_UP || newDir == ORIENT_DOWN);
|
||||||
|
|
||||||
if ((horz && nH) || (vert && nV)) {
|
if ((horz && nH) || (vert && nV)) {
|
||||||
// same axis → keep lane
|
// same axis → keep lane
|
||||||
} else if (horz && nV) {
|
} else if (horz && nV) {
|
||||||
// came off a horizontal: lane0=top→vertical.left, lane1=bottom→vertical.right
|
// came off a horizontal: lane0=top→vertical.left, lane1=bottom→vertical.right
|
||||||
newLane = (dir == ORIENT_RIGHT ? 1 : 0);
|
newLane = (dir == ORIENT_RIGHT ^ newDir == ORIENT_UP ? 0 : 1);
|
||||||
itm->offset = 0.0f;
|
itm->offset = 0.0f;
|
||||||
} else if (vert && nH) {
|
} else if (vert && nH) {
|
||||||
// came off vertical: lane0=left→horizontal.top, lane1=right→horizontal.bottom
|
// came off vertical: lane0=left→horizontal.top, lane1=right→horizontal.bottom
|
||||||
newLane = (dir == ORIENT_UP ? 0 : 1);
|
newLane = (dir == ORIENT_UP ^ newDir == ORIENT_RIGHT ? 1 : 0);
|
||||||
itm->offset = 0.0f;
|
itm->offset = 0.0f;
|
||||||
}
|
}
|
||||||
// (diagonals fall back to same-lane)
|
// (diagonals fall back to same-lane)
|
||||||
|
|
||||||
// Find a free slot in newLane
|
// Find a free slot in
|
||||||
int destSlot = -1;
|
|
||||||
if (!next->items[newLane][0].active) destSlot = 0;
|
|
||||||
else if (!next->items[newLane][1].active) destSlot = 1;
|
|
||||||
|
|
||||||
if (destSlot >= 0) {
|
if (next->items[newLane].type == 0) {
|
||||||
// MOVE it
|
// MOVE it
|
||||||
ItemOnBelt moved = *itm;
|
ItemOnBelt moved = *itm;
|
||||||
moved.tileX = nx;
|
moved.tileX = nx;
|
||||||
moved.tileY = ny;
|
moved.tileY = ny;
|
||||||
next->items[newLane][destSlot] = moved;
|
next->items[newLane] = moved;
|
||||||
next->items[newLane][destSlot].active = true;
|
|
||||||
|
|
||||||
// clear this one
|
// clear this one
|
||||||
itm->active = false;
|
itm->type = 0;
|
||||||
} else {
|
} else {
|
||||||
// both slots full → wait at end
|
// both slots full → wait at end
|
||||||
itm->offset = epsilon;
|
itm->offset = epsilon;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,8 +104,9 @@ void registerItem(char name[20], SDL_Renderer *renderer) {
|
|||||||
snprintf(texturePath, 80, "./assets/items/%s", name);
|
snprintf(texturePath, 80, "./assets/items/%s", name);
|
||||||
ItemRegistry[itemRegistryIndex].texture[ORIENT_LEFT] = IMG_LoadTexture(renderer, texturePath);
|
ItemRegistry[itemRegistryIndex].texture[ORIENT_LEFT] = IMG_LoadTexture(renderer, texturePath);
|
||||||
SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].texture[0], SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].texture[0], SDL_BLENDMODE_BLEND);
|
||||||
ItemRegistry[itemRegistryIndex].textureOnBelt[ORIENT_LEFT] = ScaleTexture(renderer, ItemRegistry[itemRegistryIndex].texture[ORIENT_LEFT],
|
ItemRegistry[itemRegistryIndex].textureOnBelt[ORIENT_LEFT] = ScaleTexture(renderer,
|
||||||
TILE_SIZE / 2, TILE_SIZE / 2);
|
ItemRegistry[itemRegistryIndex].texture[ORIENT_LEFT],
|
||||||
|
TILE_SIZE / 2, TILE_SIZE / 2);
|
||||||
SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].textureOnBelt[ORIENT_LEFT], SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].textureOnBelt[ORIENT_LEFT], SDL_BLENDMODE_BLEND);
|
||||||
ItemRegistry[itemRegistryIndex].type = itemRegistryIndex;
|
ItemRegistry[itemRegistryIndex].type = itemRegistryIndex;
|
||||||
|
|
||||||
@@ -117,19 +114,28 @@ void registerItem(char name[20], SDL_Renderer *renderer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// easing function: cosine ease‐in‐out
|
// easing function: cosine ease‐in‐out
|
||||||
|
//static float ease_in_out(float t) {
|
||||||
|
// if (t < -1.0f) t = -1.0f;
|
||||||
|
// if (t > 1.0f) t = 1.0f;
|
||||||
|
//
|
||||||
|
// // Even symmetric easing: reflected across t = 0
|
||||||
|
// return (t < 0.0f)
|
||||||
|
// ? -0.5f * (1.0f - cosf(M_PI * -t)) // negative side
|
||||||
|
// : 0.5f * (1.0f - cosf(M_PI * t)); // positive side
|
||||||
|
//}
|
||||||
|
|
||||||
static float ease_in_out(float t) {
|
static float ease_in_out(float t) {
|
||||||
|
// Clamp t to [-1.0, 1.0]
|
||||||
if (t < -1.0f) t = -1.0f;
|
if (t < -1.0f) t = -1.0f;
|
||||||
if (t > 1.0f) t = 1.0f;
|
if (t > 1.0f) t = 1.0f;
|
||||||
|
|
||||||
// Even symmetric easing: reflected across t = 0
|
return t; // Linear: no easing
|
||||||
return (t < 0.0f)
|
|
||||||
? -0.5f * (1.0f - cosf(M_PI * -t)) // negative side
|
|
||||||
: 0.5f * (1.0f - cosf(M_PI * t)); // positive side
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t laneTarget = 0;
|
uint8_t laneTarget = 0;
|
||||||
|
|
||||||
void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane) {
|
void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane, SDL_Rect playerRect) {
|
||||||
SDL_Rect rect = {0};
|
SDL_Rect rect = {0};
|
||||||
rect.x = item.tileX * TILE_SIZE;
|
rect.x = item.tileX * TILE_SIZE;
|
||||||
rect.y = item.tileY * TILE_SIZE;
|
rect.y = item.tileY * TILE_SIZE;
|
||||||
@@ -190,7 +196,7 @@ void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane) {
|
|||||||
yOffset += 0.0f * TILE_SIZE;
|
yOffset += 0.0f * TILE_SIZE;
|
||||||
break;
|
break;
|
||||||
case ORIENT_LEFT:
|
case ORIENT_LEFT:
|
||||||
xOffset += 0.0f * TILE_SIZE;
|
xOffset += 0.0f * TILE_SIZE + (TILE_SIZE / 2);
|
||||||
yOffset += 0.26f * TILE_SIZE;
|
yOffset += 0.26f * TILE_SIZE;
|
||||||
break;
|
break;
|
||||||
case ORIENT_LEFT_UP:
|
case ORIENT_LEFT_UP:
|
||||||
@@ -199,7 +205,7 @@ void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane) {
|
|||||||
break;
|
break;
|
||||||
case ORIENT_UP:
|
case ORIENT_UP:
|
||||||
xOffset += 0.22f * TILE_SIZE; //GOTO HEHREHRHE
|
xOffset += 0.22f * TILE_SIZE; //GOTO HEHREHRHE
|
||||||
yOffset += 0.0f * TILE_SIZE;
|
yOffset += 0.0f * TILE_SIZE + (TILE_SIZE / 2);
|
||||||
break;
|
break;
|
||||||
case ORIENT_RIGHT_UP:
|
case ORIENT_RIGHT_UP:
|
||||||
xOffset += 0.0f * TILE_SIZE;
|
xOffset += 0.0f * TILE_SIZE;
|
||||||
@@ -214,7 +220,7 @@ void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane) {
|
|||||||
yOffset += 0.0f * TILE_SIZE;
|
yOffset += 0.0f * TILE_SIZE;
|
||||||
break;
|
break;
|
||||||
case ORIENT_DOWN:
|
case ORIENT_DOWN:
|
||||||
xOffset += 0.18f * TILE_SIZE;
|
xOffset += 0.18f * TILE_SIZE + (TILE_SIZE / 4);
|
||||||
yOffset += 0.0f * TILE_SIZE;
|
yOffset += 0.0f * TILE_SIZE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -243,55 +249,50 @@ void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane) {
|
|||||||
rect.w = TILE_SIZE / 2;
|
rect.w = TILE_SIZE / 2;
|
||||||
rect.h = TILE_SIZE / 2;
|
rect.h = TILE_SIZE / 2;
|
||||||
|
|
||||||
adjustRect(&rect);
|
adjustRect(&rect, playerRect);
|
||||||
|
|
||||||
// (Optional debug overlay)
|
// (Optional debug overlay)
|
||||||
// SDL_Rect tileArea = {item.tileX * TILE_SIZE, item.tileY * TILE_SIZE,
|
|
||||||
// TILE_SIZE, TILE_SIZE};
|
|
||||||
// SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
|
||||||
// SDL_SetRenderDrawColor(renderer, 255, 0, 0, 32);
|
|
||||||
// adjustRect(&tileArea);
|
|
||||||
// SDL_RenderFillRect(renderer, &tileArea);
|
|
||||||
|
|
||||||
char tempStr[50];
|
char tempStr[50];
|
||||||
|
SDL_Rect rectA = {0};
|
||||||
// SDL_Rect rectA = {0};
|
if (debugMode) {
|
||||||
// rectA.x = item.tileX * TILE_SIZE;
|
SDL_Rect tileArea = {item.tileX * TILE_SIZE, item.tileY * TILE_SIZE,
|
||||||
// rectA.y = item.tileY * TILE_SIZE;
|
TILE_SIZE, TILE_SIZE};
|
||||||
// rectA.w = TILE_SIZE;
|
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 32);
|
||||||
// rectA.h = TILE_SIZE;
|
adjustRect(&tileArea, playerRect);
|
||||||
// sprintf(tempStr, "L%d\n%f\n%f\n%f", lane, item.offset, xOffset, yOffset);
|
SDL_RenderFillRect(renderer, &tileArea);
|
||||||
// SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
rectA.x = item.tileX * TILE_SIZE;
|
||||||
// SDL_SetRenderDrawColor(renderer, 255, 0, 0, 32);
|
rectA.y = item.tileY * TILE_SIZE;
|
||||||
// adjustRect(&rectA);
|
rectA.w = TILE_SIZE;
|
||||||
// SDL_RenderFillRect(renderer, &rectA);
|
rectA.h = TILE_SIZE;
|
||||||
|
sprintf(tempStr, "L%d\n%f\n%f\n%f", lane, item.offset, xOffset, yOffset);
|
||||||
|
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 32);
|
||||||
|
adjustRect(&rectA, playerRect);
|
||||||
|
SDL_RenderFillRect(renderer, &rectA);
|
||||||
|
}
|
||||||
SDL_RenderCopy(renderer, ItemRegistry[item.type].textureOnBelt[ORIENT_LEFT], NULL, &rect);
|
SDL_RenderCopy(renderer, ItemRegistry[item.type].textureOnBelt[ORIENT_LEFT], NULL, &rect);
|
||||||
// renderText(renderer, fonts[3], tempStr, rectA.x, rectA.y);
|
if (debugMode) {
|
||||||
|
renderText(renderer, fonts[3], tempStr, rectA.x, rectA.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderBeltItems(SDL_Renderer *renderer) {
|
void putItem(int x, int y, uint16_t itemType, uint8_t lane) {
|
||||||
|
tileMap[y][x].items[lane].type = itemType;
|
||||||
}
|
tileMap[y][x].items[lane].offset = 0;
|
||||||
|
tileMap[y][x].items[lane].tileX = x;
|
||||||
void putItem(int x, int y, uint16_t itemType, uint8_t lane, uint8_t itemIndex) {
|
tileMap[y][x].items[lane].tileY = y;
|
||||||
tileMap[y][x].items[lane][itemIndex].type = itemType;
|
|
||||||
tileMap[y][x].items[lane][itemIndex].offset = 0;
|
|
||||||
tileMap[y][x].items[lane][itemIndex].active = true;
|
|
||||||
tileMap[y][x].items[lane][itemIndex].tileX = x;
|
|
||||||
tileMap[y][x].items[lane][itemIndex].tileY = y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadItems(SDL_Renderer *renderer) {
|
void loadItems(SDL_Renderer *renderer) {
|
||||||
for(int i = 0; i < tileTypeIndex; i++) {
|
for (int i = 0; i < tileTypeIndex; i++) {
|
||||||
TileType tile = TileRegistry[i];
|
TileType tile = TileRegistry[i];
|
||||||
|
|
||||||
strcpy(ItemRegistry[itemRegistryIndex].name, tile.name);
|
strcpy(ItemRegistry[itemRegistryIndex].name, tile.name);
|
||||||
memcpy(ItemRegistry[itemRegistryIndex].texture, tile.textures, sizeof (tile.textures));
|
memcpy(ItemRegistry[itemRegistryIndex].texture, tile.textures, sizeof(tile.textures));
|
||||||
for (int a = 0; a < ORIENT_DIRECTION_COUNT; a++) {
|
for (int a = 0; a < ORIENT_DIRECTION_COUNT; a++) {
|
||||||
SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].texture[a], SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].texture[a], SDL_BLENDMODE_BLEND);
|
||||||
ItemRegistry[itemRegistryIndex].textureOnBelt[a] = ScaleTexture(renderer, tile.textures[a],
|
ItemRegistry[itemRegistryIndex].textureOnBelt[a] = ScaleTexture(renderer, tile.textures[a],
|
||||||
TILE_SIZE / 2, TILE_SIZE / 2);
|
TILE_SIZE / 2, TILE_SIZE / 2);
|
||||||
SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].textureOnBelt[a], SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].textureOnBelt[a], SDL_BLENDMODE_BLEND);
|
||||||
}
|
}
|
||||||
ItemRegistry[itemRegistryIndex].type = itemRegistryIndex;
|
ItemRegistry[itemRegistryIndex].type = itemRegistryIndex;
|
||||||
|
|
||||||
@@ -299,14 +300,16 @@ void loadItems(SDL_Renderer *renderer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DIR *dir = opendir("./assets/items");
|
iterateSortedDir("./assets/items", (DirEntryCallback) registerItem, renderer);
|
||||||
if (dir) {
|
|
||||||
struct dirent *entry;
|
// DIR *dir = opendir("./assets/items");
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
// if (dir) {
|
||||||
if (entry->d_name[0] == '.') {
|
// struct dirent *entry;
|
||||||
continue;
|
// while ((entry = readdir(dir)) != NULL) {
|
||||||
}
|
// if (entry->d_name[0] == '.') {
|
||||||
registerItem(entry->d_name, renderer);
|
// continue;
|
||||||
}
|
// }
|
||||||
}
|
// registerItem(entry->d_name, mainRenderer);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
@@ -14,7 +14,6 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
float offset;
|
float offset;
|
||||||
int tileX, tileY;
|
int tileX, tileY;
|
||||||
bool active;
|
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
} ItemOnBelt;
|
} ItemOnBelt;
|
||||||
|
|
||||||
@@ -30,15 +29,15 @@ extern Item ItemRegistry[ITEMREGISTRY_SIZE];
|
|||||||
|
|
||||||
void updateItems();
|
void updateItems();
|
||||||
|
|
||||||
void loadItems(SDL_Renderer *renderer);
|
void loadItems(SDL_Renderer *mainRenderer);
|
||||||
|
|
||||||
void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane);
|
void renderItem(ItemOnBelt item, SDL_Renderer *mainRenderer, int lane, SDL_Rect playerRect);
|
||||||
|
|
||||||
extern uint16_t itemRegistryIndex;
|
extern uint16_t itemRegistryIndex;
|
||||||
|
|
||||||
extern uint8_t laneTarget;
|
extern uint8_t laneTarget;
|
||||||
extern float speed;
|
extern double speed;
|
||||||
|
|
||||||
|
|
||||||
void putItem(int x, int y, uint16_t itemType, uint8_t lane, uint8_t itemIndex);
|
void putItem(int x, int y, uint16_t itemType, uint8_t lane);
|
||||||
#endif //FACTORYGAME_ITEM_H
|
#endif //FACTORYGAME_ITEM_H
|
||||||
|
264
main.c
@@ -4,18 +4,45 @@
|
|||||||
#include "util/font.h"
|
#include "util/font.h"
|
||||||
#include "util/audio.h"
|
#include "util/audio.h"
|
||||||
#include "tiles/tile.h"
|
#include "tiles/tile.h"
|
||||||
#include "tiles/belt.h"
|
|
||||||
#include "items/item.h"
|
#include "items/item.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "player/player.h"
|
#include "player/player.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Player player;
|
||||||
|
Tile tileMap[MAP_HEIGHT][MAP_WIDTH];
|
||||||
|
} GameState;
|
||||||
|
GameState gameState;
|
||||||
|
|
||||||
|
void loadGameState(char *filename, Player *plr) {
|
||||||
|
printf("hello from load\n");
|
||||||
|
fflush(stdout);
|
||||||
|
FILE *gameSave = fopen(filename, "rb");
|
||||||
|
if (gameSave) {
|
||||||
|
fread(&gameState, sizeof(gameState), 1, gameSave);
|
||||||
|
fclose(gameSave);
|
||||||
|
memcpy(tileMap, gameState.tileMap, sizeof(tileMap));
|
||||||
|
memcpy(plr, &gameState.player, sizeof(gameState.player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveGameState(char *filename, Player *plr) {
|
||||||
|
memcpy(&gameState.player, plr, sizeof(gameState.player));
|
||||||
|
memcpy(gameState.tileMap, tileMap, sizeof(gameState.tileMap));
|
||||||
|
|
||||||
|
FILE *gameSave = fopen(filename, "wb");
|
||||||
|
if (!gameSave) {
|
||||||
|
perror("Failed to open file for saving");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(&gameState, sizeof(gameState), 1, gameSave);
|
||||||
|
fclose(gameSave);
|
||||||
|
}
|
||||||
|
|
||||||
Player player;
|
Player player;
|
||||||
|
|
||||||
float currentScale = 1;
|
|
||||||
|
|
||||||
//Screen dimension constants
|
//Screen dimension constants
|
||||||
#define SCREEN_WIDTH DISPLAY_WIDTH / currentScale
|
|
||||||
#define SCREEN_HEIGHT DISPLAY_HEIGHT/ currentScale
|
|
||||||
const int targetFPS = 60;
|
const int targetFPS = 60;
|
||||||
const int delayNeeded = 1000 / targetFPS;
|
const int delayNeeded = 1000 / targetFPS;
|
||||||
|
|
||||||
@@ -24,6 +51,8 @@ const int delayNeeded = 1000 / targetFPS;
|
|||||||
#define smallerFont fonts[2]
|
#define smallerFont fonts[2]
|
||||||
#define smallestFont fonts[3]
|
#define smallestFont fonts[3]
|
||||||
|
|
||||||
|
const char *autosaveName = "autosave.dat";
|
||||||
|
|
||||||
|
|
||||||
unsigned long frames = 0;
|
unsigned long frames = 0;
|
||||||
bool cursor = true;
|
bool cursor = true;
|
||||||
@@ -35,11 +64,16 @@ void msleep(unsigned int milliseconds) {
|
|||||||
nanosleep(&ts, NULL);
|
nanosleep(&ts, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_GLContext glContext;
|
||||||
|
|
||||||
int init() {
|
int init() {
|
||||||
//Initialize SDL
|
//Initialize SDL
|
||||||
|
|
||||||
|
|
||||||
|
screenRect.x = 0;
|
||||||
|
screenRect.y = 0;
|
||||||
|
screenRect.w = DISPLAY_WIDTH;
|
||||||
|
screenRect.h = DISPLAY_HEIGHT;
|
||||||
|
|
||||||
srand(0);
|
srand(0);
|
||||||
|
|
||||||
@@ -59,24 +93,24 @@ int init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create window
|
//Create window
|
||||||
window = SDL_CreateWindow("Factory game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
|
window = SDL_CreateWindow("Factory game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, DISPLAY_WIDTH,
|
||||||
SCREEN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
DISPLAY_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
if (window == NULL) {
|
if (window == NULL) {
|
||||||
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
|
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
//Get window surface
|
//Get window surface
|
||||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
mainRenderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||||
if (renderer == NULL) {
|
if (mainRenderer == NULL) {
|
||||||
printf("Renderer could not be created SDL_Error: %s\n", SDL_GetError());
|
printf("Renderer could not be created SDL_Error: %s\n", SDL_GetError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadTiles(renderer);
|
loadTiles(mainRenderer);
|
||||||
loadItems(renderer);
|
loadItems(mainRenderer);
|
||||||
// Create OpenGL context
|
// Create OpenGL context
|
||||||
SDL_GLContext glContext = SDL_GL_CreateContext(window);
|
glContext = SDL_GL_CreateContext(window);
|
||||||
if (!glContext) {
|
if (!glContext) {
|
||||||
fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
|
fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -101,30 +135,32 @@ int init() {
|
|||||||
|
|
||||||
SDL_PauseAudioDevice(dev, 0);
|
SDL_PauseAudioDevice(dev, 0);
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(mainRenderer, 0, 0, 0, 255);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(mainRenderer);
|
||||||
|
|
||||||
SDL_Rect viewport = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
|
SDL_Rect viewport = {0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT};
|
||||||
SDL_RenderSetViewport(renderer, &viewport);
|
SDL_RenderSetViewport(mainRenderer, &viewport);
|
||||||
|
|
||||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
SDL_SetRenderDrawBlendMode(mainRenderer, SDL_BLENDMODE_BLEND);
|
||||||
biggerFont = prepText(renderer, 16, "assets/PublicPixel.ttf", 255, 255, 255, 255);
|
biggerFont = prepText(mainRenderer, 16, "assets/PublicPixel.ttf", 255, 255, 255, 255);
|
||||||
smallFont = prepText(renderer, 12, "assets/PublicPixel.ttf", 255, 255, 255, 255);
|
smallFont = prepText(mainRenderer, 12, "assets/PublicPixel.ttf", 255, 255, 255, 255);
|
||||||
smallerFont = prepText(renderer, 8, "assets/PublicPixel.ttf", 255, 255, 255, 255);
|
smallerFont = prepText(mainRenderer, 8, "assets/PublicPixel.ttf", 255, 255, 255, 255);
|
||||||
smallestFont = prepText(renderer, 4, "assets/PublicPixel.ttf", 255, 255, 255, 255);
|
smallestFont = prepText(mainRenderer, 4, "assets/PublicPixel.ttf", 255, 255, 255, 255);
|
||||||
SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);
|
SDL_RenderSetLogicalSize(mainRenderer, DISPLAY_WIDTH, DISPLAY_HEIGHT);
|
||||||
|
|
||||||
initPlayer(&player);
|
initPlayer(&player);
|
||||||
|
|
||||||
generateTestMap();
|
initTiles();
|
||||||
|
|
||||||
|
//generateTestMap();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int render() {
|
int render() {
|
||||||
SDL_SetRenderDrawColor(renderer, 32, 32, 32, 255);
|
SDL_SetRenderDrawColor(mainRenderer, 32, 32, 32, 255);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(mainRenderer);
|
||||||
|
|
||||||
SDL_Rect rect2;
|
SDL_Rect rect2;
|
||||||
rect2.x = 20;
|
rect2.x = 20;
|
||||||
@@ -132,12 +168,17 @@ int render() {
|
|||||||
rect2.w = 0;
|
rect2.w = 0;
|
||||||
rect2.h = 0;
|
rect2.h = 0;
|
||||||
|
|
||||||
renderAllBelts(renderer);
|
renderAllTiles(mainRenderer, player.rect);
|
||||||
|
|
||||||
|
SDL_RenderCopy(mainRenderer, tilesTexture, &screenRect, &screenRect);
|
||||||
|
SDL_RenderCopy(mainRenderer, itemsTexture, &screenRect, &screenRect);
|
||||||
|
SDL_RenderCopy(mainRenderer, entityTexture, &screenRect, &screenRect);
|
||||||
|
SDL_RenderCopy(mainRenderer, hudTexture, &screenRect, &screenRect);
|
||||||
|
|
||||||
renderPlayer(&player);
|
renderPlayer(&player);
|
||||||
|
|
||||||
|
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(mainRenderer);
|
||||||
frames++;
|
frames++;
|
||||||
if (!(frames % 60)) {
|
if (!(frames % 60)) {
|
||||||
cursor = !cursor;
|
cursor = !cursor;
|
||||||
@@ -154,10 +195,11 @@ int processEvent(SDL_Event e) {
|
|||||||
|
|
||||||
// Adjust the viewport to match the new window size;
|
// Adjust the viewport to match the new window size;
|
||||||
SDL_Rect viewport = {0, 0, newWidth, newHeight};
|
SDL_Rect viewport = {0, 0, newWidth, newHeight};
|
||||||
SDL_RenderSetViewport(renderer, &viewport);
|
SDL_RenderSetViewport(mainRenderer, &viewport);
|
||||||
} else if (e.type == SDL_KEYDOWN) {
|
} else if (e.type == SDL_KEYDOWN) {
|
||||||
int keySym = e.key.keysym.sym;
|
SDL_KeyCode keySym = e.key.keysym.sym;
|
||||||
int keyMod = e.key.keysym.mod;
|
SDL_Scancode scanCode = e.key.keysym.scancode;
|
||||||
|
SDL_Keymod keyMod = e.key.keysym.mod;
|
||||||
cursor = true;
|
cursor = true;
|
||||||
switch (keySym) {
|
switch (keySym) {
|
||||||
case SDLK_p:
|
case SDLK_p:
|
||||||
@@ -172,6 +214,12 @@ int processEvent(SDL_Event e) {
|
|||||||
player.cursor.targetTile->direction = player.cursor.direction;
|
player.cursor.targetTile->direction = player.cursor.direction;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SDLK_u:
|
||||||
|
laneTarget = !laneTarget;
|
||||||
|
break;
|
||||||
|
case SDLK_F3:
|
||||||
|
debugMode = !debugMode;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -203,7 +251,7 @@ int processEvent(SDL_Event e) {
|
|||||||
|
|
||||||
void processMousePosition() {
|
void processMousePosition() {
|
||||||
SDL_Rect viewport;
|
SDL_Rect viewport;
|
||||||
SDL_RenderGetViewport(renderer, &viewport);
|
SDL_RenderGetViewport(mainRenderer, &viewport);
|
||||||
|
|
||||||
uint32_t mouseButtons = SDL_GetMouseState(&player.cursor.windowX, &player.cursor.windowY);
|
uint32_t mouseButtons = SDL_GetMouseState(&player.cursor.windowX, &player.cursor.windowY);
|
||||||
if (mouseButtons & SDL_BUTTON_LMASK) {
|
if (mouseButtons & SDL_BUTTON_LMASK) {
|
||||||
@@ -228,14 +276,12 @@ void processMousePosition() {
|
|||||||
}
|
}
|
||||||
if (player.cursor.targetTile->type == TYPE_BELT) {
|
if (player.cursor.targetTile->type == TYPE_BELT) {
|
||||||
for (int lane = 0; lane < 2; lane++) {
|
for (int lane = 0; lane < 2; lane++) {
|
||||||
for (int slot = 0; slot < 2; slot++) {
|
if (player.cursor.targetTile->items[lane].type != 0) {
|
||||||
if (player.cursor.targetTile->items[lane][slot].active) {
|
int itemType = player.cursor.targetTile->items[lane].type;
|
||||||
int itemType = player.cursor.targetTile->items[lane][slot].type;
|
if (itemType < itemRegistryIndex) {
|
||||||
if (itemType < itemRegistryIndex) {
|
player.inventory.slotCounts[itemType]++;
|
||||||
player.inventory.slotCounts[itemType]++;
|
|
||||||
}
|
|
||||||
player.cursor.targetTile->items[lane][slot].active = false;
|
|
||||||
}
|
}
|
||||||
|
player.cursor.targetTile->items[lane].type = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,12 +307,20 @@ void processMousePosition() {
|
|||||||
}
|
}
|
||||||
// Translate mouseRect coordinates to viewport space
|
// Translate mouseRect coordinates to viewport space
|
||||||
|
|
||||||
player.cursor.windowX = ((player.cursor.windowX - viewport.x) * SCREEN_WIDTH) / viewport.w;
|
player.cursor.windowX = ((player.cursor.windowX - viewport.x) * DISPLAY_WIDTH) / viewport.w;
|
||||||
player.cursor.windowY = (player.cursor.windowY - viewport.y) * SCREEN_HEIGHT / viewport.h;
|
player.cursor.windowY = (player.cursor.windowY - viewport.y) * DISPLAY_HEIGHT / viewport.h;
|
||||||
player.cursor.tileX = (player.cursor.windowX + playerX) / TILE_SIZE - (SCREEN_WIDTH / TILE_SIZE / 2);
|
player.cursor.tileX = (player.cursor.windowX + player.rect.x) / TILE_SIZE - (DISPLAY_WIDTH / TILE_SIZE / 2);
|
||||||
player.cursor.tileY = (player.cursor.windowY + playerY) / TILE_SIZE - (SCREEN_HEIGHT / TILE_SIZE / 2);
|
player.cursor.tileY = (player.cursor.windowY + player.rect.y) / TILE_SIZE - (DISPLAY_HEIGHT / TILE_SIZE / 2);
|
||||||
player.cursor.prevTargetTile = player.cursor.targetTile;
|
player.cursor.prevTargetTile = player.cursor.targetTile;
|
||||||
player.cursor.targetTile = &tileMap[player.cursor.tileY][player.cursor.tileX];
|
player.cursor.targetTile = &tileMap[player.cursor.tileY][player.cursor.tileX];
|
||||||
|
|
||||||
|
player.cursor.targetTileRect.x = player.cursor.tileX * TILE_SIZE;
|
||||||
|
player.cursor.targetTileRect.y = player.cursor.tileY * TILE_SIZE;
|
||||||
|
player.cursor.tileDiffX = player.cursor.tileX - playerTileX;
|
||||||
|
player.cursor.tileDiffY = player.cursor.tileY - playerTileY;
|
||||||
|
player.cursor.tileDiff = floorf(sqrtf(powf(player.cursor.tileDiffX, 2) + powf(player.cursor.tileDiffY, 2)));
|
||||||
|
player.cursor.canReach = player.cursor.tileDiff <= playerReach;
|
||||||
|
adjustRect(&player.cursor.targetTileRect, player.rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void processKeyboardHeld() {
|
void processKeyboardHeld() {
|
||||||
@@ -281,29 +335,54 @@ void processKeyboardHeld() {
|
|||||||
cameraSpeed /= 2;
|
cameraSpeed /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyboardState[SDL_SCANCODE_W]) {
|
if (player.cursor.breakingProgress == 0) {
|
||||||
// Example: move up
|
if (keyboardState[SDL_SCANCODE_W]) {
|
||||||
playerY -= cameraSpeed;
|
// Example: move up
|
||||||
if (playerY < (SCREEN_HEIGHT / 2)) {
|
player.rect.y -= cameraSpeed;
|
||||||
playerY = (SCREEN_HEIGHT / 2);
|
if (player.rect.y < (DISPLAY_HEIGHT / 2)) {
|
||||||
|
player.rect.y = (DISPLAY_HEIGHT / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keyboardState[SDL_SCANCODE_S]) {
|
||||||
|
player.rect.y += cameraSpeed;
|
||||||
|
if (player.rect.y > (MAP_HEIGHT * TILE_SIZE) - (DISPLAY_HEIGHT / 2)) {
|
||||||
|
player.rect.y = (MAP_HEIGHT * TILE_SIZE) - (DISPLAY_HEIGHT / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keyboardState[SDL_SCANCODE_A]) {
|
||||||
|
player.rect.x -= cameraSpeed;
|
||||||
|
if (player.rect.x < (DISPLAY_WIDTH / 2)) {
|
||||||
|
player.rect.x = (DISPLAY_WIDTH / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keyboardState[SDL_SCANCODE_D]) {
|
||||||
|
player.rect.x += cameraSpeed;
|
||||||
|
if (player.rect.x > (MAP_WIDTH * TILE_SIZE) - (DISPLAY_WIDTH / 2)) {
|
||||||
|
player.rect.x = (MAP_WIDTH * TILE_SIZE) - (DISPLAY_WIDTH / 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (keyboardState[SDL_SCANCODE_S]) {
|
|
||||||
playerY += cameraSpeed;
|
if (keyboardState[SDL_SCANCODE_F]) {
|
||||||
if (playerY > (MAP_HEIGHT * TILE_SIZE) - (SCREEN_HEIGHT / 2)) {
|
for (int x = player.rect.x - 1; x < player.rect.x + 1; player.rect.x++) {
|
||||||
playerY = (MAP_HEIGHT * TILE_SIZE) - (SCREEN_HEIGHT / 2);
|
if (x < 0) {
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
if (keyboardState[SDL_SCANCODE_A]) {
|
for (int y = player.rect.y - 1; y < player.rect.y + 1; player.rect.y++) {
|
||||||
playerX -= cameraSpeed;
|
if (y < 0) {
|
||||||
if (playerX < (SCREEN_WIDTH / 2)) {
|
continue;
|
||||||
playerX = (SCREEN_WIDTH / 2);
|
}
|
||||||
}
|
Tile *t = &tileMap[y][x];
|
||||||
}
|
if (t->type == TYPE_BELT) {
|
||||||
if (keyboardState[SDL_SCANCODE_D]) {
|
for (uint8_t lane = 0; lane < 2; lane++) {
|
||||||
playerX += cameraSpeed;
|
ItemOnBelt *item = &t->items[lane];
|
||||||
if (playerX > (MAP_WIDTH * TILE_SIZE) - (SCREEN_WIDTH / 2)) {
|
if (item->type != 0) {
|
||||||
playerX = (MAP_WIDTH * TILE_SIZE) - (SCREEN_WIDTH / 2);
|
player.inventory.slotCounts[item->type]++;
|
||||||
|
item->type = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,22 +394,46 @@ void processKeyboardHeld() {
|
|||||||
if (keyboardState[SDL_SCANCODE_Y]) {
|
if (keyboardState[SDL_SCANCODE_Y]) {
|
||||||
if (player.cursor.canReach && player.cursor.targetTile->type == TYPE_BELT &&
|
if (player.cursor.canReach && player.cursor.targetTile->type == TYPE_BELT &&
|
||||||
player.inventory.slotCounts[player.inventory.activeSlotIndex] > 0) {
|
player.inventory.slotCounts[player.inventory.activeSlotIndex] > 0) {
|
||||||
bool done = false;
|
for (uint8_t lane = 0; lane < 1; lane++) {
|
||||||
for (uint8_t lane = 0; lane < 2; lane++) {
|
if (player.cursor.targetTile->items[lane].type == 0) {
|
||||||
for (uint8_t slot = 0; slot < 2; slot++) {
|
putItem(player.cursor.tileX, player.cursor.tileY, player.inventory.activeSlotIndex, lane);
|
||||||
if (!player.cursor.targetTile->items[lane][slot].active) {
|
player.inventory.slotCounts[player.inventory.activeSlotIndex]--;
|
||||||
putItem(player.cursor.tileX, player.cursor.tileY, player.inventory.activeSlotIndex, lane, slot);
|
|
||||||
player.inventory.slotCounts[player.inventory.activeSlotIndex]--;
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (done) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unsigned int slot = 0;
|
||||||
|
if (keyboardState[SDL_SCANCODE_GRAVE]) {
|
||||||
|
slot = 1;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_1]) {
|
||||||
|
slot = 2;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_2]) {
|
||||||
|
slot = 3;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_3]) {
|
||||||
|
slot = 4;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_4]) {
|
||||||
|
slot = 5;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_5]) {
|
||||||
|
slot = 6;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_6]) {
|
||||||
|
slot = 7;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_7]) {
|
||||||
|
slot = 8;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_8]) {
|
||||||
|
slot = 9;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_9]) {
|
||||||
|
slot = 10;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_0]) {
|
||||||
|
slot = 11;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_MINUS]) {
|
||||||
|
slot = 12;
|
||||||
|
} else if (keyboardState[SDL_SCANCODE_EQUALS]) {
|
||||||
|
slot = 13;
|
||||||
|
}
|
||||||
|
if (slot > 0 && slot < itemRegistryIndex) {
|
||||||
|
setActivePlayerSlot(&player, slot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(__attribute__((unused)) int argc, __attribute__((unused)) char *args[]) {
|
int main(__attribute__((unused)) int argc, __attribute__((unused)) char *args[]) {
|
||||||
@@ -338,13 +441,7 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char *args[])
|
|||||||
if (status) {
|
if (status) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
loadGameState(autosaveName, &player);
|
||||||
uint8_t type = 0;
|
|
||||||
for (int x = 142; x < 154; x += 3) {
|
|
||||||
for (int y = 80; y < 94; y += 3) {
|
|
||||||
putItem(x, y, type++ % ITEMREGISTRY_SIZE, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Hack to get window to stay up
|
//Hack to get window to stay up
|
||||||
@@ -375,12 +472,15 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char *args[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveGameState(autosaveName, &player);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < fontCount; i++) {
|
for (uint8_t i = 0; i < fontCount; i++) {
|
||||||
destroyFont(&fonts[i]);
|
destroyFont(&fonts[i]);
|
||||||
}
|
}
|
||||||
puts(SDL_GetError());
|
puts(SDL_GetError());
|
||||||
if (renderer) SDL_DestroyRenderer(renderer);
|
if (mainRenderer) SDL_DestroyRenderer(mainRenderer);
|
||||||
if (window) SDL_DestroyWindow(window);
|
if (window) SDL_DestroyWindow(window);
|
||||||
|
if (glContext) SDL_GL_DeleteContext(glContext);
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
|
210
player/player.c
@@ -5,16 +5,27 @@
|
|||||||
#include <SDL2/SDL_rect.h>
|
#include <SDL2/SDL_rect.h>
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "../tiles/tile.h"
|
#include "../tiles/tile.h"
|
||||||
|
#include "../util/font.h"
|
||||||
|
|
||||||
#define HEALTH_MARGIN 4
|
#define HEALTH_MARGIN 4
|
||||||
|
|
||||||
int playerSpeed = 4;
|
int playerSpeed = 2;
|
||||||
|
|
||||||
int playerReach = 4;
|
int playerReach = DISPLAY_MAP_HEIGHT / 2 - 2;
|
||||||
|
|
||||||
|
SDL_Texture *entityTexture;
|
||||||
|
SDL_Texture *hudTexture;
|
||||||
|
|
||||||
SDL_Texture *PlayerTexture;
|
SDL_Texture *PlayerTexture;
|
||||||
SDL_Rect PlayerRect;
|
SDL_Rect PlayerRect;
|
||||||
|
|
||||||
|
SDL_Rect targetItemBGRect;
|
||||||
|
|
||||||
|
SDL_Rect targetItemRect;
|
||||||
|
|
||||||
|
SDL_Color healthBarColor = {0, 240, 0, 255};
|
||||||
|
SDL_Color breakingBarColor = {128, 128, 0, 255};
|
||||||
|
|
||||||
void setActivePlayerSlot(Player *plr, uint16_t activeSlotIndex) {
|
void setActivePlayerSlot(Player *plr, uint16_t activeSlotIndex) {
|
||||||
activeSlotIndex = activeSlotIndex % itemRegistryIndex;
|
activeSlotIndex = activeSlotIndex % itemRegistryIndex;
|
||||||
if (activeSlotIndex <= 0) {
|
if (activeSlotIndex <= 0) {
|
||||||
@@ -35,7 +46,7 @@ void moveActivePlayerSlot(Player *plr, bool up, bool seek) {
|
|||||||
if (newSlot == prevSlot) break;
|
if (newSlot == prevSlot) break;
|
||||||
|
|
||||||
// Stop if we found a slot with count > 0
|
// Stop if we found a slot with count > 0
|
||||||
if (plr->inventory.slotCounts[newSlot] > 0) break;
|
if (plr->inventory.slotCounts[newSlot] > 0 && newSlot != 0) break;
|
||||||
} while (true);
|
} while (true);
|
||||||
plr->inventory.activeSlotIndex = newSlot;
|
plr->inventory.activeSlotIndex = newSlot;
|
||||||
} else {
|
} else {
|
||||||
@@ -52,58 +63,88 @@ void moveActivePlayerSlot(Player *plr, bool up, bool seek) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void adjustRect(SDL_Rect *rect, SDL_Rect playerRect) {
|
||||||
int playerX = (MAP_WIDTH / 2) * 16;
|
rect->x -= playerRect.x;
|
||||||
int playerY = (MAP_HEIGHT / 2) * 16;
|
rect->y -= playerRect.y;
|
||||||
|
|
||||||
void adjustRect(SDL_Rect *rect) {
|
|
||||||
rect->x -= playerX;
|
|
||||||
rect->y -= playerY;
|
|
||||||
rect->x += DISPLAY_WIDTH / 2;
|
rect->x += DISPLAY_WIDTH / 2;
|
||||||
rect->y += DISPLAY_HEIGHT / 2;
|
rect->y += DISPLAY_HEIGHT / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInboundsTile(int x, int y) {
|
//bool isInboundsTile(int x, int y) {
|
||||||
return (playerX / TILE_SIZE) - (DISPLAY_MAP_WIDTH / 2) < x &&
|
// return (playerX / TILE_SIZE) - (DISPLAY_MAP_WIDTH / 2) < x &&
|
||||||
(playerY / TILE_SIZE) - (DISPLAY_MAP_HEIGHT / 2) < y &&
|
// (playerY / TILE_SIZE) - (DISPLAY_MAP_HEIGHT / 2) < y &&
|
||||||
(playerX / TILE_SIZE) + (DISPLAY_MAP_WIDTH / 2) > x && (playerX / TILE_SIZE) + (DISPLAY_MAP_WIDTH / 2) > y;
|
// (playerX / TILE_SIZE) + (DISPLAY_MAP_WIDTH / 2) > x && (playerX / TILE_SIZE) + (DISPLAY_MAP_WIDTH / 2) > y;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
|
//bool isInbounds(int x, int y) {
|
||||||
|
// return x > 0 && y > 0 && x < DISPLAY_WIDTH && y < DISPLAY_HEIGHT;
|
||||||
|
//}
|
||||||
|
|
||||||
bool isInbounds(int x, int y) {
|
//bool isInboundsRect(SDL_Rect rect) {
|
||||||
return x > 0 && y > 0 && x < DISPLAY_WIDTH && y < DISPLAY_HEIGHT;
|
// if (isInbounds(rect.x, rect.y)) {
|
||||||
}
|
// return true;
|
||||||
|
// }
|
||||||
bool isInboundsRect(SDL_Rect rect) {
|
// if (rect.x < 0) {
|
||||||
if (isInbounds(rect.x, rect.y)) {
|
// rect.x += rect.w;
|
||||||
return true;
|
// }
|
||||||
}
|
// if (rect.y < 0) {
|
||||||
if (rect.x < 0) {
|
// rect.y += rect.h;
|
||||||
rect.x += rect.w;
|
// }
|
||||||
}
|
// if (isInbounds(rect.x, rect.y)) {
|
||||||
if (rect.y < 0) {
|
// return true;
|
||||||
rect.y += rect.h;
|
// }
|
||||||
}
|
// if (rect.x > DISPLAY_WIDTH) {
|
||||||
if (isInbounds(rect.x, rect.y)) {
|
// rect.x -= rect.w;
|
||||||
return true;
|
// }
|
||||||
}
|
// if (rect.y > DISPLAY_HEIGHT) {
|
||||||
if (rect.x > DISPLAY_WIDTH) {
|
// rect.y -= rect.h;
|
||||||
rect.x -= rect.w;
|
// }
|
||||||
}
|
// return isInbounds(rect.x, rect.y);
|
||||||
if (rect.y > DISPLAY_HEIGHT) {
|
//}
|
||||||
rect.y -= rect.h;
|
|
||||||
}
|
|
||||||
return isInbounds(rect.x, rect.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void initPlayer(Player *plr) {
|
void initPlayer(Player *plr) {
|
||||||
plr->cursor.direction = ORIENT_UP;
|
plr->cursor.direction = ORIENT_UP;
|
||||||
setActivePlayerSlot(plr, 1);
|
setActivePlayerSlot(plr, 1);
|
||||||
PlayerTexture = IMG_LoadTexture(renderer, "assets/player.png");
|
PlayerTexture = IMG_LoadTexture(mainRenderer, "assets/player.png");
|
||||||
SDL_QueryTexture(PlayerTexture, NULL, NULL, &PlayerRect.w, &PlayerRect.h);
|
SDL_QueryTexture(PlayerTexture, NULL, NULL, &PlayerRect.w, &PlayerRect.h);
|
||||||
PlayerRect.x = (DISPLAY_WIDTH / 2) - (PlayerRect.w / 2);
|
PlayerRect.x = (DISPLAY_WIDTH / 2) - (PlayerRect.w / 2);
|
||||||
PlayerRect.y = (DISPLAY_HEIGHT / 2) - (PlayerRect.h / 2);
|
PlayerRect.y = (DISPLAY_HEIGHT / 2) - (PlayerRect.h / 2);
|
||||||
plr->health = 64;
|
plr->health = 64;
|
||||||
plr->healthIdle = 0;
|
plr->healthIdle = 0;
|
||||||
|
|
||||||
|
plr->rect.x = DISPLAY_WIDTH / 2;
|
||||||
|
plr->rect.y = DISPLAY_HEIGHT / 2;
|
||||||
|
plr->rect.w = TILE_SIZE;
|
||||||
|
plr->rect.h = TILE_SIZE;
|
||||||
|
|
||||||
|
for (uint16_t ui = 0; ui < itemRegistryIndex; ui++) {
|
||||||
|
plr->inventory.slotCounts[ui] = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
hudTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, screenRect.w,
|
||||||
|
screenRect.h);
|
||||||
|
entityTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, screenRect.w,
|
||||||
|
screenRect.h);
|
||||||
|
|
||||||
|
SDL_SetTextureBlendMode(entityTexture, SDL_BLENDMODE_BLEND);
|
||||||
|
SDL_SetTextureBlendMode(hudTexture, SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
|
plr->cursor.targetTileRect.w = TILE_SIZE;
|
||||||
|
plr->cursor.targetTileRect.h = TILE_SIZE;
|
||||||
|
|
||||||
|
plr->cursor.targetTileRect.w = TILE_SIZE;
|
||||||
|
plr->cursor.targetTileRect.h = TILE_SIZE;
|
||||||
|
|
||||||
|
targetItemBGRect.w = DISPLAY_WIDTH;
|
||||||
|
targetItemBGRect.h = TILE_SIZE;
|
||||||
|
targetItemBGRect.x = 0;
|
||||||
|
targetItemBGRect.y = DISPLAY_HEIGHT - 32;
|
||||||
|
|
||||||
|
targetItemRect.w = TILE_SIZE / 2;
|
||||||
|
targetItemRect.h = TILE_SIZE / 2;
|
||||||
|
|
||||||
|
plr->cursor.heldItemRect.w = TILE_SIZE;
|
||||||
|
plr->cursor.heldItemRect.h = TILE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePlayer(Player *plr) {
|
void updatePlayer(Player *plr) {
|
||||||
@@ -118,31 +159,26 @@ void updatePlayer(Player *plr) {
|
|||||||
|
|
||||||
void renderPlayer(Player *plr) {
|
void renderPlayer(Player *plr) {
|
||||||
|
|
||||||
plr->cursor.targetTileRect.x = plr->cursor.tileX * TILE_SIZE;
|
SDL_Texture *originalTarget = SDL_GetRenderTarget(mainRenderer);
|
||||||
plr->cursor.targetTileRect.y = plr->cursor.tileY * TILE_SIZE;
|
|
||||||
plr->cursor.targetTileRect.w = TILE_SIZE;
|
SDL_SetRenderDrawColor(mainRenderer, 0, 0, 0, 0);
|
||||||
plr->cursor.targetTileRect.h = TILE_SIZE;
|
|
||||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
SDL_SetRenderTarget(mainRenderer, entityTexture);
|
||||||
plr->cursor.tileDiffX = plr->cursor.tileX - playerTileX;
|
SDL_RenderClear(mainRenderer);
|
||||||
plr->cursor.tileDiffY = plr->cursor.tileY - playerTileY;
|
SDL_RenderCopy(mainRenderer, PlayerTexture, NULL, &PlayerRect);
|
||||||
if (abs(plr->cursor.tileDiffX) > abs(plr->cursor.tileDiffY)) {
|
SDL_SetRenderTarget(mainRenderer, hudTexture);
|
||||||
plr->cursor.tileDiff = plr->cursor.tileDiffX;
|
SDL_RenderClear(mainRenderer);
|
||||||
} else {
|
|
||||||
plr->cursor.tileDiff = plr->cursor.tileDiffY;
|
SDL_SetRenderDrawColor(mainRenderer, plr->cursor.canReach ? 0 : 255, plr->cursor.canReach ? 255 : 0, 0, 128);
|
||||||
}
|
DrawThickRect(mainRenderer, plr->cursor.targetTileRect, 4);
|
||||||
plr->cursor.canReach = abs(plr->cursor.tileDiff) <= playerReach;
|
|
||||||
SDL_SetRenderDrawColor(renderer, plr->cursor.canReach ? 0 : 255, plr->cursor.canReach ? 255 : 0, 0, 128);
|
|
||||||
adjustRect(&plr->cursor.targetTileRect);
|
|
||||||
DrawThickRect(renderer, plr->cursor.targetTileRect, 4);
|
|
||||||
|
|
||||||
uint16_t itemIndex = plr->inventory.activeSlotIndex;
|
uint16_t itemIndex = plr->inventory.activeSlotIndex;
|
||||||
|
SDL_Texture *itemTex;
|
||||||
|
char itemStringCount[6];
|
||||||
if (itemIndex < itemRegistryIndex) {
|
if (itemIndex < itemRegistryIndex) {
|
||||||
SDL_Rect heldItemRect;
|
plr->cursor.heldItemRect.x = plr->cursor.windowX;
|
||||||
heldItemRect.x = plr->cursor.windowX;
|
plr->cursor.heldItemRect.y = plr->cursor.windowY;
|
||||||
heldItemRect.y = plr->cursor.windowY;
|
itemTex = ItemRegistry[itemIndex].textureOnBelt[plr->cursor.direction];
|
||||||
heldItemRect.w = TILE_SIZE;
|
|
||||||
heldItemRect.h = TILE_SIZE;
|
|
||||||
SDL_Texture *itemTex = ItemRegistry[itemIndex].textureOnBelt[plr->cursor.direction];
|
|
||||||
if (itemTex == NULL) {
|
if (itemTex == NULL) {
|
||||||
itemTex = ItemRegistry[itemIndex].textureOnBelt[ORIENT_LEFT];
|
itemTex = ItemRegistry[itemIndex].textureOnBelt[ORIENT_LEFT];
|
||||||
}
|
}
|
||||||
@@ -158,37 +194,29 @@ void renderPlayer(Player *plr) {
|
|||||||
|
|
||||||
SDL_SetTextureAlphaMod(itemTex, 255);
|
SDL_SetTextureAlphaMod(itemTex, 255);
|
||||||
}
|
}
|
||||||
SDL_RenderCopy(renderer, itemTex, NULL,
|
SDL_RenderCopy(mainRenderer, itemTex, NULL,
|
||||||
&heldItemRect);
|
&plr->cursor.heldItemRect);
|
||||||
|
renderText(mainRenderer, fonts[2], ItemRegistry[itemIndex].name, plr->cursor.heldItemRect.x,
|
||||||
|
plr->cursor.heldItemRect.y - (fonts[2].size * 3 / 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SDL_RenderCopy(renderer, PlayerTexture, NULL, &PlayerRect);
|
|
||||||
|
|
||||||
SDL_Color healthBarColor = {0, 240, 0, 255};
|
|
||||||
|
|
||||||
renderBar(renderer, (DISPLAY_WIDTH / 2) - 128, DISPLAY_HEIGHT - 50, 200, 8, playerMaxHealth, plr->health, healthBarColor, 4);
|
renderBar(mainRenderer, (DISPLAY_WIDTH / 2) - 128, DISPLAY_HEIGHT - 50, 200, 8, playerMaxHealth, plr->health,
|
||||||
|
healthBarColor, 4);
|
||||||
|
|
||||||
SDL_Color breakingBarColor = {128, 128, 0, 255};
|
renderBar(mainRenderer, (DISPLAY_WIDTH / 2) - 128, DISPLAY_HEIGHT - 70, 200, 8,
|
||||||
|
|
||||||
renderBar(renderer, (DISPLAY_WIDTH / 2) - 128, DISPLAY_HEIGHT - 70, 200, 8,
|
|
||||||
getBreakTime(plr->cursor.targetTile->type), plr->cursor.breakingProgress, breakingBarColor, 4);
|
getBreakTime(plr->cursor.targetTile->type), plr->cursor.breakingProgress, breakingBarColor, 4);
|
||||||
|
|
||||||
SDL_Rect targetItemBGRect;
|
|
||||||
targetItemBGRect.w = DISPLAY_WIDTH;
|
|
||||||
targetItemBGRect.h = TILE_SIZE;
|
|
||||||
targetItemBGRect.x = 0;
|
|
||||||
targetItemBGRect.y = DISPLAY_HEIGHT - 30;
|
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
|
||||||
SDL_RenderFillRect(renderer, &targetItemBGRect);
|
|
||||||
|
|
||||||
SDL_Rect targetItemRect;
|
SDL_SetRenderDrawColor(mainRenderer, 0, 0, 0, 255);
|
||||||
targetItemRect.w = TILE_SIZE / 2;
|
SDL_RenderFillRect(mainRenderer, &targetItemBGRect);
|
||||||
targetItemRect.h = TILE_SIZE / 2;
|
|
||||||
targetItemRect.y = DISPLAY_HEIGHT - 30 + TILE_SIZE / 4;
|
targetItemRect.y = DISPLAY_HEIGHT - 30 + TILE_SIZE / 4 + 3;
|
||||||
targetItemRect.x = TILE_SIZE / 4;
|
targetItemRect.x = TILE_SIZE / 4;
|
||||||
|
|
||||||
for (uint16_t i = 1; i < ITEMREGISTRY_SIZE; i++) {
|
for (uint16_t i = 1; i < itemRegistryIndex; i++) {
|
||||||
SDL_Texture *itemTex = ItemRegistry[i].textureOnBelt[plr->cursor.direction];
|
itemTex = ItemRegistry[i].textureOnBelt[plr->cursor.direction];
|
||||||
if (itemTex == NULL) {
|
if (itemTex == NULL) {
|
||||||
itemTex = ItemRegistry[i].textureOnBelt[ORIENT_LEFT];
|
itemTex = ItemRegistry[i].textureOnBelt[ORIENT_LEFT];
|
||||||
}
|
}
|
||||||
@@ -197,15 +225,21 @@ void renderPlayer(Player *plr) {
|
|||||||
// Set a red tint (255, 0, 0)
|
// Set a red tint (255, 0, 0)
|
||||||
SDL_SetTextureColorMod(itemTex, 128, 128, 255);
|
SDL_SetTextureColorMod(itemTex, 128, 128, 255);
|
||||||
}
|
}
|
||||||
SDL_RenderCopy(renderer, itemTex, NULL, &targetItemRect);
|
SDL_RenderCopy(mainRenderer, itemTex, NULL, &targetItemRect);
|
||||||
SDL_SetTextureColorMod(itemTex, 255, 255, 255);
|
SDL_SetTextureColorMod(itemTex, 255, 255, 255);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (plr->inventory.activeSlotIndex == i) {
|
if (plr->inventory.activeSlotIndex == i) {
|
||||||
SDL_SetRenderDrawColor(renderer, 16, plr->inventory.slotCounts[i] > 0 ? 128 : 16,
|
SDL_SetRenderDrawColor(mainRenderer, 16, plr->inventory.slotCounts[i] > 0 ? 128 : 16,
|
||||||
plr->inventory.slotCounts[i] > 0 ? 32 : 128, 255);
|
plr->inventory.slotCounts[i] > 0 ? 32 : 128, 255);
|
||||||
DrawThickRect(renderer, targetItemRect, 4);
|
DrawThickRect(mainRenderer, targetItemRect, 4);
|
||||||
}
|
}
|
||||||
targetItemRect.x += (TILE_SIZE / 2) + (TILE_SIZE / 4);
|
sprintf(itemStringCount, "%d", plr->inventory.slotCounts[i]);
|
||||||
|
renderText(mainRenderer, fonts[2], itemStringCount, targetItemRect.x - 3,
|
||||||
|
targetItemRect.y - (fonts[2].size * 3 / 2));
|
||||||
|
//targetItemRect.x += (TILE_SIZE / 2) + (TILE_SIZE / 4);
|
||||||
|
targetItemRect.x += TILE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_SetRenderTarget(mainRenderer, originalTarget);
|
||||||
}
|
}
|
@@ -9,19 +9,20 @@
|
|||||||
#include "../items/item.h"
|
#include "../items/item.h"
|
||||||
|
|
||||||
extern int playerReach;
|
extern int playerReach;
|
||||||
extern int playerX;
|
#define playerTileX (player.rect.x / TILE_SIZE)
|
||||||
extern int playerY;
|
#define playerTileY (player.rect.y / TILE_SIZE)
|
||||||
#define playerTileX (playerX / TILE_SIZE)
|
|
||||||
#define playerTileY (playerY / TILE_SIZE)
|
|
||||||
extern int playerSpeed;
|
extern int playerSpeed;
|
||||||
|
|
||||||
bool isInbounds(int x, int y);
|
extern SDL_Texture *entityTexture;
|
||||||
|
extern SDL_Texture *hudTexture;
|
||||||
|
|
||||||
bool isInboundsRect(SDL_Rect rect);
|
//bool isInbounds(int x, int y);
|
||||||
|
//
|
||||||
|
//bool isInboundsRect(SDL_Rect rect);
|
||||||
|
//
|
||||||
|
//bool isInboundsTile(int x, int y);
|
||||||
|
|
||||||
bool isInboundsTile(int x, int y);
|
void adjustRect(SDL_Rect *rect, SDL_Rect playerRect);
|
||||||
|
|
||||||
void adjustRect(SDL_Rect *rect);
|
|
||||||
|
|
||||||
#define neededHealthIdle 120
|
#define neededHealthIdle 120
|
||||||
|
|
||||||
@@ -45,25 +46,26 @@ typedef struct {
|
|||||||
SDL_Rect targetTileRect;
|
SDL_Rect targetTileRect;
|
||||||
Tile *targetTile;
|
Tile *targetTile;
|
||||||
Tile *prevTargetTile;
|
Tile *prevTargetTile;
|
||||||
|
SDL_Rect heldItemRect;
|
||||||
int breakingProgress;
|
int breakingProgress;
|
||||||
} PlayerCursor;
|
} PlayerCursor;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PlayerCursor cursor;
|
PlayerCursor cursor;
|
||||||
PlayerInventory inventory;
|
PlayerInventory inventory;
|
||||||
SDL_Renderer *renderer;
|
|
||||||
uint8_t health;
|
uint8_t health;
|
||||||
uint8_t prevHealth;
|
uint8_t prevHealth;
|
||||||
uint8_t healthIdle;
|
uint8_t healthIdle;
|
||||||
|
SDL_Rect rect;
|
||||||
} Player;
|
} Player;
|
||||||
|
|
||||||
void setActivePlayerSlot(Player * plr, uint16_t activeSlotIndex);
|
void setActivePlayerSlot(Player *plr, uint16_t activeSlotIndex);
|
||||||
|
|
||||||
void moveActivePlayerSlot(Player *plr, bool up, bool seek);
|
void moveActivePlayerSlot(Player *plr, bool up, bool seek);
|
||||||
|
|
||||||
void renderPlayer(Player * plr);
|
void renderPlayer(Player *plr);
|
||||||
|
|
||||||
void initPlayer(Player * plr);
|
void initPlayer(Player *plr);
|
||||||
|
|
||||||
void updatePlayer(Player *plr);
|
void updatePlayer(Player *plr);
|
||||||
|
|
||||||
|
67
tiles/belt.c
@@ -9,16 +9,14 @@
|
|||||||
#include "../player/player.h"
|
#include "../player/player.h"
|
||||||
#include "../items/item.h"
|
#include "../items/item.h"
|
||||||
|
|
||||||
static int scrollFrame = 0;
|
|
||||||
unsigned long beltFrames = 0;
|
|
||||||
|
|
||||||
|
|
||||||
void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Renderer *renderer) {
|
|
||||||
|
|
||||||
|
void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Rect playerRect, SDL_Renderer *renderer) {
|
||||||
int px = x * TILE_SIZE;
|
int px = x * TILE_SIZE;
|
||||||
int py = y * TILE_SIZE;
|
int py = y * TILE_SIZE;
|
||||||
|
|
||||||
uint16_t tileType = tileMap[y][x].type;
|
Tile *t = &tileMap[y][x];
|
||||||
|
|
||||||
|
uint16_t tileType = t->type;
|
||||||
|
|
||||||
SDL_Rect src1, src2, dst1, dst2;
|
SDL_Rect src1, src2, dst1, dst2;
|
||||||
|
|
||||||
@@ -35,8 +33,8 @@ void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Renderer *r
|
|||||||
src2 = (SDL_Rect) {0, 0, offset, TILE_SIZE};
|
src2 = (SDL_Rect) {0, 0, offset, TILE_SIZE};
|
||||||
dst2 = (SDL_Rect) {px + (w - offset), py, offset, h};
|
dst2 = (SDL_Rect) {px + (w - offset), py, offset, h};
|
||||||
|
|
||||||
adjustRect(&dst1);
|
adjustRect(&dst1, playerRect);
|
||||||
adjustRect(&dst2);
|
adjustRect(&dst2, playerRect);
|
||||||
|
|
||||||
SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src1, &dst1);
|
SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src1, &dst1);
|
||||||
SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src2, &dst2);
|
SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src2, &dst2);
|
||||||
@@ -53,60 +51,19 @@ void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Renderer *r
|
|||||||
src2 = (SDL_Rect) {0, 0, TILE_SIZE, offset};
|
src2 = (SDL_Rect) {0, 0, TILE_SIZE, offset};
|
||||||
dst2 = (SDL_Rect) {px, py + (h - offset), w, offset};
|
dst2 = (SDL_Rect) {px, py + (h - offset), w, offset};
|
||||||
|
|
||||||
adjustRect(&dst1);
|
adjustRect(&dst1, playerRect);
|
||||||
adjustRect(&dst2);
|
adjustRect(&dst2, playerRect);
|
||||||
|
|
||||||
|
|
||||||
// Rotate to make the belt vertical
|
// Rotate to make the belt vertical
|
||||||
SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src1, &dst1);
|
SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src1, &dst1);
|
||||||
SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src2, &dst2);
|
SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src2, &dst2);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
SDL_SetRenderTarget(renderer, itemsTexture);
|
||||||
void renderAllBelts(SDL_Renderer *renderer) {
|
for (uint8_t lane = 0; lane < 2; lane++) {
|
||||||
int scrollSpeed = 1; // pixels per step
|
if (t->items[lane].type != 0) {
|
||||||
int scrollDelay = 1; // frames between steps
|
renderItem(t->items[lane], renderer, lane, playerRect);
|
||||||
|
|
||||||
if (beltFrames++ % scrollDelay == 0) {
|
|
||||||
scrollFrame += scrollSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tileSize = TILE_SIZE;
|
|
||||||
for (int y = (playerY / TILE_SIZE) - (DISPLAY_MAP_HEIGHT / 2) - 1;
|
|
||||||
y < (playerY / TILE_SIZE) + (DISPLAY_MAP_HEIGHT / 2) + 1; y++) {
|
|
||||||
if (y < 0 || y >= MAP_HEIGHT) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (int x = (playerX / TILE_SIZE) - (DISPLAY_MAP_WIDTH / 2) - 1;
|
|
||||||
x < (playerX / TILE_SIZE) + (DISPLAY_MAP_WIDTH / 2) + 1; x++) {
|
|
||||||
if (x < 0 || x >= MAP_WIDTH) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Tile t = tileMap[y][x];
|
|
||||||
if (t.type != TYPE_BELT) continue;
|
|
||||||
renderBelt(x, y, tileSize, tileSize, t.direction, renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int y = (playerY / TILE_SIZE) - (DISPLAY_MAP_HEIGHT / 2) - 1;
|
|
||||||
y < (playerY / TILE_SIZE) + (DISPLAY_MAP_HEIGHT / 2) + 1; y++) {
|
|
||||||
if (y < 0 || y >= MAP_HEIGHT) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (int x = (playerX / TILE_SIZE) - (DISPLAY_MAP_WIDTH / 2) - 1;
|
|
||||||
x < (playerX / TILE_SIZE) + (DISPLAY_MAP_WIDTH / 2) + 1; x++) {
|
|
||||||
if (x < 0 || x >= MAP_WIDTH) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Tile t = tileMap[y][x];
|
|
||||||
if (t.type != TYPE_BELT) continue;
|
|
||||||
for (uint8_t lane = 0; lane < 2; lane++) {
|
|
||||||
for (uint8_t itemIndex = 0; itemIndex < 2; itemIndex++) {
|
|
||||||
if (t.items[lane][itemIndex].active) {
|
|
||||||
renderItem(t.items[lane][itemIndex], renderer, lane);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,13 +4,12 @@
|
|||||||
|
|
||||||
#ifndef FACTORYGAME_BELT_H
|
#ifndef FACTORYGAME_BELT_H
|
||||||
#define FACTORYGAME_BELT_H
|
#define FACTORYGAME_BELT_H
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_image.h>
|
#include <SDL2/SDL_image.h>
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include "../util/util.h"
|
#include "../util/util.h"
|
||||||
|
|
||||||
void renderBelt(int px, int py, int w, int h, OrientDirection dir, SDL_Renderer * renderer);
|
void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Rect playerRect, SDL_Renderer *renderer);
|
||||||
|
|
||||||
void renderAllBelts(SDL_Renderer * renderer);
|
|
||||||
|
|
||||||
#endif //FACTORYGAME_BELT_H
|
#endif //FACTORYGAME_BELT_H
|
||||||
|
14
tiles/furnace.c
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// Created by bruno on 31.5.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "furnace.h"
|
||||||
|
#include "tile.h"
|
||||||
|
|
||||||
|
uint16_t getFurnaceNewItem(uint16_t sourceItem) {
|
||||||
|
uint16_t realItemIndex = sourceItem - tileTypeIndex - 1;
|
||||||
|
if (realItemIndex < 8) {
|
||||||
|
return sourceItem + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
10
tiles/furnace.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
//
|
||||||
|
// Created by bruno on 31.5.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef FACTORYGAME_FURNACE_H
|
||||||
|
#define FACTORYGAME_FURNACE_H
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
#endif //FACTORYGAME_FURNACE_H
|
103
tiles/tile.c
@@ -4,10 +4,17 @@
|
|||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
#include "../player/player.h"
|
||||||
|
|
||||||
|
int scrollFrame = 0;
|
||||||
|
unsigned long beltFrames = 0;
|
||||||
|
|
||||||
|
SDL_Texture *tilesTexture;
|
||||||
|
SDL_Texture *itemsTexture;
|
||||||
|
|
||||||
Tile tileMap[MAP_HEIGHT][MAP_WIDTH];
|
Tile tileMap[MAP_HEIGHT][MAP_WIDTH];
|
||||||
|
|
||||||
uint16_t tileTypeIndex = 1;
|
uint16_t tileTypeIndex = 0;
|
||||||
|
|
||||||
TileType TileRegistry[TILEREGISTRY_SIZE];
|
TileType TileRegistry[TILEREGISTRY_SIZE];
|
||||||
|
|
||||||
@@ -31,6 +38,13 @@ void generateTestMap() {
|
|||||||
tileMap[y][x].direction = (rand() % 4 * 2) + 1;
|
tileMap[y][x].direction = (rand() % 4 * 2) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t type = 0;
|
||||||
|
for (int x = 142; x < 154; x += 3) {
|
||||||
|
for (int y = 80; y < 94; y += 3) {
|
||||||
|
putItem(x, y, type++ % ITEMREGISTRY_SIZE, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -45,23 +59,25 @@ void registerTile(char name[20], SDL_Renderer *renderer) {
|
|||||||
TileRegistry[tileTypeIndex].textures[ORIENT_UP] = createRotatedTexture(renderer, texture, 90);
|
TileRegistry[tileTypeIndex].textures[ORIENT_UP] = createRotatedTexture(renderer, texture, 90);
|
||||||
TileRegistry[tileTypeIndex].textures[ORIENT_DOWN] = createRotatedTexture(renderer, texture, 270);
|
TileRegistry[tileTypeIndex].textures[ORIENT_DOWN] = createRotatedTexture(renderer, texture, 270);
|
||||||
TileRegistry[tileTypeIndex].type = tileTypeIndex;
|
TileRegistry[tileTypeIndex].type = tileTypeIndex;
|
||||||
TileRegistry[tileTypeIndex].breakTime = 30;
|
TileRegistry[tileTypeIndex].breakTime = 15;
|
||||||
|
|
||||||
tileTypeIndex++;
|
tileTypeIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void loadTiles(SDL_Renderer *renderer) {
|
void loadTiles(SDL_Renderer *renderer) {
|
||||||
DIR *dir = opendir("./assets/tiles");
|
iterateSortedDir("./assets/tiles", (DirEntryCallback) registerTile, renderer);
|
||||||
if (dir) {
|
// DIR *dir = opendir("./assets/tiles");
|
||||||
struct dirent *entry;
|
// if (dir) {
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
// struct dirent *entry;
|
||||||
if (entry->d_name[0] == '.') {
|
// while ((entry = readdir(dir)) != NULL) {
|
||||||
continue;
|
// if (entry->d_name[0] == '.') {
|
||||||
}
|
// continue;
|
||||||
registerTile(entry->d_name, renderer);
|
// }
|
||||||
}
|
// registerTile(entry->d_name, mainRenderer);
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
TileRegistry[0].breakTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getBreakTime(int type) {
|
uint16_t getBreakTime(int type) {
|
||||||
@@ -70,3 +86,66 @@ uint16_t getBreakTime(int type) {
|
|||||||
}
|
}
|
||||||
return TileRegistry[type].breakTime;
|
return TileRegistry[type].breakTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initTiles() {
|
||||||
|
itemsTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, screenRect.w,
|
||||||
|
screenRect.h);
|
||||||
|
tilesTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, screenRect.w,
|
||||||
|
screenRect.h);
|
||||||
|
SDL_SetTextureBlendMode(itemsTexture, SDL_BLENDMODE_BLEND);
|
||||||
|
SDL_SetTextureBlendMode(tilesTexture, SDL_BLENDMODE_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderAllTiles(SDL_Renderer *renderer, SDL_Rect playerRect) {
|
||||||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||||
|
SDL_Texture *oldTarget = SDL_GetRenderTarget(renderer);
|
||||||
|
SDL_SetRenderTarget(renderer, itemsTexture);
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
SDL_SetRenderTarget(renderer, tilesTexture);
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
int scrollSpeed = 1; // pixels per step
|
||||||
|
int scrollDelay = 1; // frames between steps
|
||||||
|
|
||||||
|
if (beltFrames++ % scrollDelay == 0) {
|
||||||
|
scrollFrame += scrollSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tileSize = TILE_SIZE;
|
||||||
|
for (int y = (playerRect.y / TILE_SIZE) - (DISPLAY_MAP_HEIGHT / 2) - 1;
|
||||||
|
y < (playerRect.y / TILE_SIZE) + (DISPLAY_MAP_HEIGHT / 2) + 1; y++) {
|
||||||
|
if (y < 0 || y >= MAP_HEIGHT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int x = (playerRect.x / TILE_SIZE) - (DISPLAY_MAP_WIDTH / 2) - 1;
|
||||||
|
x < (playerRect.x / TILE_SIZE) + (DISPLAY_MAP_WIDTH / 2) + 1; x++) {
|
||||||
|
if (x < 0 || x >= MAP_WIDTH) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Tile t = tileMap[y][x];
|
||||||
|
SDL_SetRenderTarget(renderer, tilesTexture);
|
||||||
|
switch (t.type) {
|
||||||
|
case TYPE_BELT:
|
||||||
|
renderBelt(x, y, tileSize, tileSize, t.direction, playerRect, renderer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_Rect dstRect;
|
||||||
|
dstRect.x = x * TILE_SIZE;
|
||||||
|
dstRect.y = y * TILE_SIZE;
|
||||||
|
dstRect.w = TILE_SIZE;
|
||||||
|
dstRect.h = TILE_SIZE;
|
||||||
|
adjustRect(&dstRect, playerRect);
|
||||||
|
SDL_Texture *tex = TileRegistry[t.type].textures[t.direction];
|
||||||
|
if (tex == NULL) {
|
||||||
|
tex = TileRegistry[t.type].textures[ORIENT_LEFT];
|
||||||
|
}
|
||||||
|
if (tex != NULL) {
|
||||||
|
SDL_RenderCopy(renderer, tex, NULL, &dstRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (t.type == TYPE_BELT) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_SetRenderTarget(renderer, oldTarget);
|
||||||
|
}
|
18
tiles/tile.h
@@ -12,14 +12,20 @@
|
|||||||
#define MAP_WIDTH 600
|
#define MAP_WIDTH 600
|
||||||
#define MAP_HEIGHT 340
|
#define MAP_HEIGHT 340
|
||||||
|
|
||||||
#define DISPLAY_MAP_WIDTH 30
|
#define DISPLAY_MAP_WIDTH 44
|
||||||
#define DISPLAY_MAP_HEIGHT 16
|
#define DISPLAY_MAP_HEIGHT 22
|
||||||
|
|
||||||
#define TILE_SIZE 32
|
#define TILE_SIZE 32
|
||||||
|
|
||||||
#define DISPLAY_WIDTH DISPLAY_MAP_WIDTH * TILE_SIZE
|
#define DISPLAY_WIDTH DISPLAY_MAP_WIDTH * TILE_SIZE
|
||||||
#define DISPLAY_HEIGHT DISPLAY_MAP_HEIGHT * TILE_SIZE
|
#define DISPLAY_HEIGHT DISPLAY_MAP_HEIGHT * TILE_SIZE
|
||||||
|
|
||||||
|
extern SDL_Texture *tilesTexture;
|
||||||
|
extern SDL_Texture *itemsTexture;
|
||||||
|
|
||||||
|
extern int scrollFrame;
|
||||||
|
extern unsigned long beltFrames;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
char name[20];
|
char name[20];
|
||||||
@@ -32,13 +38,15 @@ typedef struct {
|
|||||||
extern TileType TileRegistry[TILEREGISTRY_SIZE];
|
extern TileType TileRegistry[TILEREGISTRY_SIZE];
|
||||||
|
|
||||||
#define TYPE_AIR 0
|
#define TYPE_AIR 0
|
||||||
#define TYPE_BELT 1
|
#define TYPE_BELT 2
|
||||||
|
|
||||||
|
void renderAllTiles(SDL_Renderer * renderer, SDL_Rect playerRect);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
OrientDirection direction;
|
OrientDirection direction;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
int frameOffset;
|
int frameOffset;
|
||||||
ItemOnBelt items[2][2];
|
ItemOnBelt items[2];
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
} Tile;
|
} Tile;
|
||||||
@@ -52,4 +60,6 @@ extern uint16_t tileTypeIndex;
|
|||||||
|
|
||||||
uint16_t getBreakTime(int type);
|
uint16_t getBreakTime(int type);
|
||||||
|
|
||||||
|
void initTiles();
|
||||||
|
|
||||||
#endif //FACTORYGAME_TILE_H
|
#endif //FACTORYGAME_TILE_H
|
||||||
|
@@ -18,7 +18,7 @@ void audio_callback(void *userdata, Uint8 *stream, int len) {
|
|||||||
SynthVoice *voice = &audio->synthVoices[v];
|
SynthVoice *voice = &audio->synthVoices[v];
|
||||||
if (voice->volume == 0 || voice->frequency == 0) continue;
|
if (voice->volume == 0 || voice->frequency == 0) continue;
|
||||||
|
|
||||||
float sample = 0.0f;
|
float sample;
|
||||||
float t = (float) voice->phase / 255.0f * 2.0f - 1.0f;
|
float t = (float) voice->phase / 255.0f * 2.0f - 1.0f;
|
||||||
|
|
||||||
switch (voice->waveform) {
|
switch (voice->waveform) {
|
||||||
|
81
util/util.c
@@ -2,6 +2,7 @@
|
|||||||
// Created by bruno on 4/24/25.
|
// Created by bruno on 4/24/25.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
//#include "font.h"
|
//#include "font.h"
|
||||||
|
|
||||||
@@ -9,16 +10,20 @@
|
|||||||
SDL_Window *window = NULL;
|
SDL_Window *window = NULL;
|
||||||
volatile bool running = true;
|
volatile bool running = true;
|
||||||
|
|
||||||
//The surface contained by the window
|
bool debugMode = false;
|
||||||
SDL_Renderer *renderer = NULL;
|
|
||||||
|
|
||||||
SDL_Texture* createFlippedTexture(SDL_Renderer* renderer, SDL_Texture* src, SDL_RendererFlip flip) {
|
//The surface contained by the window
|
||||||
|
SDL_Renderer *mainRenderer = NULL;
|
||||||
|
|
||||||
|
SDL_Rect screenRect;
|
||||||
|
|
||||||
|
SDL_Texture *createFlippedTexture(SDL_Renderer *renderer, SDL_Texture *src, SDL_RendererFlip flip) {
|
||||||
int w, h;
|
int w, h;
|
||||||
SDL_QueryTexture(src, NULL, NULL, &w, &h);
|
SDL_QueryTexture(src, NULL, NULL, &w, &h);
|
||||||
|
|
||||||
SDL_Texture *renderTarget = SDL_GetRenderTarget(renderer);
|
SDL_Texture *renderTarget = SDL_GetRenderTarget(renderer);
|
||||||
|
|
||||||
SDL_Texture* target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
|
SDL_Texture *target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
|
||||||
SDL_SetRenderTarget(renderer, target);
|
SDL_SetRenderTarget(renderer, target);
|
||||||
SDL_RenderCopyEx(renderer, src, NULL, NULL, 0, NULL, flip);
|
SDL_RenderCopyEx(renderer, src, NULL, NULL, 0, NULL, flip);
|
||||||
SDL_SetRenderTarget(renderer, renderTarget);
|
SDL_SetRenderTarget(renderer, renderTarget);
|
||||||
@@ -26,12 +31,12 @@ SDL_Texture* createFlippedTexture(SDL_Renderer* renderer, SDL_Texture* src, SDL_
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Texture* createRotatedTexture(SDL_Renderer* renderer, SDL_Texture* src, double angle) {
|
SDL_Texture *createRotatedTexture(SDL_Renderer *renderer, SDL_Texture *src, double angle) {
|
||||||
int w, h;
|
int w, h;
|
||||||
SDL_QueryTexture(src, NULL, NULL, &w, &h);
|
SDL_QueryTexture(src, NULL, NULL, &w, &h);
|
||||||
SDL_Texture *renderTarget = SDL_GetRenderTarget(renderer);
|
SDL_Texture *renderTarget = SDL_GetRenderTarget(renderer);
|
||||||
|
|
||||||
SDL_Texture* target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
|
SDL_Texture *target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
|
||||||
SDL_SetRenderTarget(renderer, target);
|
SDL_SetRenderTarget(renderer, target);
|
||||||
SDL_RenderCopyEx(renderer, src, NULL, NULL, angle, NULL, SDL_FLIP_NONE);
|
SDL_RenderCopyEx(renderer, src, NULL, NULL, angle, NULL, SDL_FLIP_NONE);
|
||||||
SDL_SetRenderTarget(renderer, renderTarget);
|
SDL_SetRenderTarget(renderer, renderTarget);
|
||||||
@@ -39,8 +44,8 @@ SDL_Texture* createRotatedTexture(SDL_Renderer* renderer, SDL_Texture* src, doub
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Texture* ScaleTexture(SDL_Renderer* renderer, SDL_Texture* src, int newWidth, int newHeight) {
|
SDL_Texture *ScaleTexture(SDL_Renderer *renderer, SDL_Texture *src, int newWidth, int newHeight) {
|
||||||
SDL_Texture* scaledTex = SDL_CreateTexture(renderer,
|
SDL_Texture *scaledTex = SDL_CreateTexture(renderer,
|
||||||
SDL_PIXELFORMAT_RGBA8888,
|
SDL_PIXELFORMAT_RGBA8888,
|
||||||
SDL_TEXTUREACCESS_TARGET,
|
SDL_TEXTUREACCESS_TARGET,
|
||||||
newWidth,
|
newWidth,
|
||||||
@@ -52,13 +57,13 @@ SDL_Texture* ScaleTexture(SDL_Renderer* renderer, SDL_Texture* src, int newWidth
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save current render target
|
// Save current render target
|
||||||
SDL_Texture* oldTarget = SDL_GetRenderTarget(renderer);
|
SDL_Texture *oldTarget = SDL_GetRenderTarget(renderer);
|
||||||
|
|
||||||
SDL_SetRenderTarget(renderer, scaledTex);
|
SDL_SetRenderTarget(renderer, scaledTex);
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
SDL_Rect dst = { 0, 0, newWidth, newHeight };
|
SDL_Rect dst = {0, 0, newWidth, newHeight};
|
||||||
SDL_RenderCopy(renderer, src, NULL, &dst);
|
SDL_RenderCopy(renderer, src, NULL, &dst);
|
||||||
|
|
||||||
SDL_SetRenderTarget(renderer, oldTarget); // Restore
|
SDL_SetRenderTarget(renderer, oldTarget); // Restore
|
||||||
@@ -66,9 +71,9 @@ SDL_Texture* ScaleTexture(SDL_Renderer* renderer, SDL_Texture* src, int newWidth
|
|||||||
return scaledTex;
|
return scaledTex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawThickRect(SDL_Renderer* renderer, SDL_Rect rect, int thickness) {
|
void DrawThickRect(SDL_Renderer *renderer, SDL_Rect rect, int thickness) {
|
||||||
for (int i = 0; i < thickness; i++) {
|
for (int i = 0; i < thickness; i++) {
|
||||||
SDL_Rect r = { rect.x - i, rect.y - i, rect.w + i * 2, rect.h + i * 2 };
|
SDL_Rect r = {rect.x - i, rect.y - i, rect.w + i * 2, rect.h + i * 2};
|
||||||
SDL_RenderDrawRect(renderer, &r);
|
SDL_RenderDrawRect(renderer, &r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,8 +81,7 @@ void DrawThickRect(SDL_Renderer* renderer, SDL_Rect rect, int thickness) {
|
|||||||
void renderBar(SDL_Renderer *renderer,
|
void renderBar(SDL_Renderer *renderer,
|
||||||
int x, int y, int width, int height,
|
int x, int y, int width, int height,
|
||||||
int maxValue, int currentValue,
|
int maxValue, int currentValue,
|
||||||
SDL_Color barColor, int margin)
|
SDL_Color barColor, int margin) {
|
||||||
{
|
|
||||||
if (maxValue <= 0) return; // Avoid division by zero
|
if (maxValue <= 0) return; // Avoid division by zero
|
||||||
|
|
||||||
// Clamp value
|
// Clamp value
|
||||||
@@ -91,7 +95,7 @@ void renderBar(SDL_Renderer *renderer,
|
|||||||
int filledWidth = (width * currentValue) / maxValue;
|
int filledWidth = (width * currentValue) / maxValue;
|
||||||
|
|
||||||
// Bar rectangle
|
// Bar rectangle
|
||||||
SDL_Rect barRect = { x, y, filledWidth, height };
|
SDL_Rect barRect = {x, y, filledWidth, height};
|
||||||
|
|
||||||
// Background rectangle with margin
|
// Background rectangle with margin
|
||||||
SDL_Rect bgRect = {
|
SDL_Rect bgRect = {
|
||||||
@@ -112,5 +116,50 @@ void renderBar(SDL_Renderer *renderer,
|
|||||||
char barString[20];
|
char barString[20];
|
||||||
sprintf(barString, "%d/%d", currentValue, maxValue);
|
sprintf(barString, "%d/%d", currentValue, maxValue);
|
||||||
|
|
||||||
//renderText(renderer, fonts[3], barString, width / 2, margin);
|
//renderText(mainRenderer, fonts[3], barString, width / 2, margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmpstringp(const void *p1, const void *p2) {
|
||||||
|
return strcmp(*(const char **)p1, *(const char **)p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function to iterate over sorted entries in a directory
|
||||||
|
void iterateSortedDir(const char *path, DirEntryCallback callback, SDL_Renderer *renderer) {
|
||||||
|
DIR *dir = opendir(path);
|
||||||
|
if (!dir) {
|
||||||
|
perror("opendir");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent *entry;
|
||||||
|
char **names = NULL;
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
// Collect file names
|
||||||
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
|
if (entry->d_name[0] == '.') continue;
|
||||||
|
names = realloc(names, sizeof(char *) * (count + 1));
|
||||||
|
if (!names) {
|
||||||
|
perror("realloc");
|
||||||
|
closedir(dir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
names[count++] = strdup(entry->d_name);
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
// Sort entries
|
||||||
|
qsort(names, count, sizeof(char *), cmpstringp);
|
||||||
|
|
||||||
|
// Call the user-provided function for each file
|
||||||
|
if (names != NULL) {
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
if (names[i] != NULL) {
|
||||||
|
callback(names[i], renderer);
|
||||||
|
free(names[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(names);
|
||||||
|
}
|
||||||
}
|
}
|
12
util/util.h
@@ -11,7 +11,9 @@ extern SDL_Window *window;
|
|||||||
extern volatile bool running;
|
extern volatile bool running;
|
||||||
|
|
||||||
//The surface contained by the window
|
//The surface contained by the window
|
||||||
extern SDL_Renderer *renderer;
|
extern SDL_Renderer *mainRenderer;
|
||||||
|
|
||||||
|
extern SDL_Rect screenRect;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ORIENT_LEFT_DOWN,
|
ORIENT_LEFT_DOWN,
|
||||||
@@ -25,6 +27,8 @@ typedef enum {
|
|||||||
ORIENT_DIRECTION_COUNT
|
ORIENT_DIRECTION_COUNT
|
||||||
} OrientDirection;
|
} OrientDirection;
|
||||||
|
|
||||||
|
extern bool debugMode;
|
||||||
|
|
||||||
SDL_Texture *createRotatedTexture(SDL_Renderer *renderer, SDL_Texture *src, double angle);
|
SDL_Texture *createRotatedTexture(SDL_Renderer *renderer, SDL_Texture *src, double angle);
|
||||||
|
|
||||||
SDL_Texture *createFlippedTexture(SDL_Renderer *renderer, SDL_Texture *src, SDL_RendererFlip flip);
|
SDL_Texture *createFlippedTexture(SDL_Renderer *renderer, SDL_Texture *src, SDL_RendererFlip flip);
|
||||||
@@ -33,6 +37,12 @@ SDL_Texture* ScaleTexture(SDL_Renderer* renderer, SDL_Texture* src, int newWidth
|
|||||||
|
|
||||||
void DrawThickRect(SDL_Renderer* renderer, SDL_Rect rect, int thickness);
|
void DrawThickRect(SDL_Renderer* renderer, SDL_Rect rect, int thickness);
|
||||||
|
|
||||||
|
// Define a function pointer type for your callback
|
||||||
|
typedef void (*DirEntryCallback)(const char *filename, SDL_Renderer *renderer);
|
||||||
|
|
||||||
|
// Helper function to iterate over sorted entries in a directory
|
||||||
|
void iterateSortedDir(const char *path, DirEntryCallback callback, SDL_Renderer *renderer);
|
||||||
|
|
||||||
void renderBar(SDL_Renderer *renderer,
|
void renderBar(SDL_Renderer *renderer,
|
||||||
int x, int y, int width, int height,
|
int x, int y, int width, int height,
|
||||||
int maxValue, int currentValue,
|
int maxValue, int currentValue,
|
||||||
|