Start atlas

This commit is contained in:
2025-06-01 22:13:02 +02:00
parent 96a9a45c20
commit 84805b92cb
64 changed files with 954 additions and 243 deletions

View File

@@ -16,7 +16,7 @@ void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Rect player
Tile *t = &tileMap[y][x];
uint16_t tileType = t->type;
ItemType tileType = t->type;
SDL_Rect src1, src2, dst1, dst2;
@@ -59,11 +59,8 @@ void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Rect player
SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src1, &dst1);
SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src2, &dst2);
}
}
void updateBelt(Tile * tile) {
SDL_SetRenderTarget(renderer, itemsTexture);
for (uint8_t lane = 0; lane < 2; lane++) {
if (t->items[lane].type != 0) {
renderItem(t->items[lane], renderer, lane, playerRect);
}
}
}

View File

@@ -7,9 +7,12 @@
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "tile.h"
#include "../util/util.h"
struct Tile;
void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Rect playerRect, SDL_Renderer *renderer);
void updateBelt(struct Tile * tile);
#endif //FACTORYGAME_BELT_H

View File

@@ -4,11 +4,48 @@
#include "furnace.h"
#include "tile.h"
#include "../util/audio.h"
uint16_t getFurnaceNewItem(uint16_t sourceItem) {
uint16_t realItemIndex = sourceItem - tileTypeIndex - 1;
if (realItemIndex < 8) {
return sourceItem + 1;
const ItemType FurnaceRecipes[ITEMREGISTRY_SIZE] = {
[IRON_ORE] = IRON_INGOT,
[SILVER_ORE] = SILVER_INGOT,
[GOLD_ORE] = GOLD_INGOT,
[PLATINUM_ORE] = PLATINUM_INGOT
};
void updateFurnace(Tile *tile) {
ItemOnBelt *inItem = &tile->items[FURNACE_INPUT_SLOT];
ItemOnBelt *outItem = &tile->items[FURNACE_OUTPUT_SLOT];
Item inItemType = ItemRegistry[inItem->type];
ItemType targetOutItemType = FurnaceRecipes[inItem->type];
Item targetOutItem = ItemRegistry[targetOutItemType];
if (targetOutItemType != TYPE_AIR) {
if (tile->miscVal == 0) {
tile->audioCh = getAvailableChannel();
if (tile->audioCh < NUM_SYNTH_VOICES) {
audioData.synthVoices[tile->audioCh].volume = 1;
audioData.synthVoices[tile->audioCh].phase = 0;
audioData.synthVoices[tile->audioCh].sourceRect.x = TILE_SIZE * tile->x;
audioData.synthVoices[tile->audioCh].sourceRect.y = TILE_SIZE * tile->y;
audioData.synthVoices[tile->audioCh].waveform = WAVE_TRIANGLE;
audioData.synthVoices[tile->audioCh].frequency = 99;
}
}
if (tile->audioCh < NUM_SYNTH_VOICES) {
audioData.synthVoices[tile->audioCh].frequency++;
}
if (outItem->type == 0 && ++tile->miscVal >= targetOutItem.miscVal) {
if (tile->audioCh < NUM_SYNTH_VOICES) {
audioData.synthVoices[tile->audioCh].volume = 0;
}
tile->miscVal = 0;
inItem->type = 0;
outItem->type = targetOutItemType;
outItem->offset = -0.5f;
}
}
return 0;
}

View File

@@ -5,6 +5,14 @@
#ifndef FACTORYGAME_FURNACE_H
#define FACTORYGAME_FURNACE_H
#include "../items/item.h"
#include "stdint.h"
extern const ItemType FurnaceRecipes[];
#define FURNACE_INPUT_SLOT 0
#define FURNACE_OUTPUT_SLOT 1
void updateFurnace(Tile * tile);
#endif //FACTORYGAME_FURNACE_H

View File

@@ -5,18 +5,26 @@
#include <dirent.h>
#include "tile.h"
#include "../player/player.h"
#include "furnace.h"
#include "../util/atlas.h"
int scrollFrame = 0;
unsigned long beltFrames = 0;
SDL_Texture *backgroundTexture;
SDL_Texture *tilesTexture;
SDL_Texture *itemsTexture;
Tile tileMap[MAP_HEIGHT][MAP_WIDTH];
uint16_t tileTypeIndex = 0;
BackgroundTile backgroundMap[MAP_HEIGHT][MAP_WIDTH];
uint16_t tileTypeIndex = 0;
uint16_t backgroundTileTypeIndex = 0;
TileTypeReg TileRegistry[TILEREGISTRY_SIZE];
BackgroundTileType BackgroundTileRegistry[TILEREGISTRY_SIZE];
TileType TileRegistry[TILEREGISTRY_SIZE];
void generateTestMap() {
for (int y = 0; y < DISPLAY_MAP_HEIGHT; y++) {
@@ -32,7 +40,7 @@ void generateTestMap() {
for (int y = 0; y < MAP_HEIGHT; y += 1) {
tileMap[y][x].type = TYPE_BELT;
tileMap[y][x].frameOffset = 0;
tileMap[y][x].miscVal = 0;
//tileMap[y][x].direction = ((x + y) % 4 * 2) + 1;
//tileMap[y][x].direction = 5;
tileMap[y][x].direction = (rand() % 4 * 2) + 1;
@@ -58,26 +66,68 @@ void registerTile(char name[20], SDL_Renderer *renderer) {
TileRegistry[tileTypeIndex].textures[ORIENT_RIGHT] = createFlippedTexture(renderer, texture, SDL_FLIP_HORIZONTAL);
TileRegistry[tileTypeIndex].textures[ORIENT_UP] = createRotatedTexture(renderer, texture, 90);
TileRegistry[tileTypeIndex].textures[ORIENT_DOWN] = createRotatedTexture(renderer, texture, 270);
if (tileTypeIndex == 0) {
SDL_SetTextureAlphaMod(TileRegistry[0].textures[ORIENT_LEFT], 64);
SDL_SetTextureAlphaMod(TileRegistry[0].textures[ORIENT_RIGHT], 64);
SDL_SetTextureAlphaMod(TileRegistry[0].textures[ORIENT_UP], 64);
SDL_SetTextureAlphaMod(TileRegistry[0].textures[ORIENT_DOWN], 64);
}
SDL_SetTextureBlendMode(TileRegistry[tileTypeIndex].textures[ORIENT_LEFT], SDL_BLENDMODE_BLEND);
SDL_SetTextureBlendMode(TileRegistry[tileTypeIndex].textures[ORIENT_RIGHT], SDL_BLENDMODE_BLEND);
SDL_SetTextureBlendMode(TileRegistry[tileTypeIndex].textures[ORIENT_UP], SDL_BLENDMODE_BLEND);
SDL_SetTextureBlendMode(TileRegistry[tileTypeIndex].textures[ORIENT_DOWN], SDL_BLENDMODE_BLEND);
TileRegistry[tileTypeIndex].atlasRects[ORIENT_LEFT] = allocate_32x32(TileRegistry[tileTypeIndex].textures[ORIENT_LEFT], renderer);
TileRegistry[tileTypeIndex].atlasRects[ORIENT_RIGHT] = allocate_32x32(TileRegistry[tileTypeIndex].textures[ORIENT_RIGHT], renderer);
TileRegistry[tileTypeIndex].atlasRects[ORIENT_UP] = allocate_32x32(TileRegistry[tileTypeIndex].textures[ORIENT_UP], renderer);
TileRegistry[tileTypeIndex].atlasRects[ORIENT_DOWN] = allocate_32x32(TileRegistry[tileTypeIndex].textures[ORIENT_DOWN], renderer);
TileRegistry[tileTypeIndex].type = tileTypeIndex;
TileRegistry[tileTypeIndex].breakTime = 15;
tileTypeIndex++;
}
void registerBackgroundTile(char name[20], SDL_Renderer *renderer) {
const char *dot = strchr(name, '.');
memcpy(BackgroundTileRegistry[backgroundTileTypeIndex].name, name, dot - name);
char texturePath[80];
snprintf(texturePath, 80, "./assets/backgrounds/%s", name);
SDL_Texture *texture = IMG_LoadTexture(renderer, texturePath);
BackgroundTileRegistry[backgroundTileTypeIndex].texture = texture;
SDL_SetTextureBlendMode(BackgroundTileRegistry[backgroundTileTypeIndex].texture, SDL_BLENDMODE_NONE);
BackgroundTileRegistry[backgroundTileTypeIndex].atlasRect = allocate_32x32(BackgroundTileRegistry[backgroundTileTypeIndex].texture, renderer);
BackgroundTileRegistry[backgroundTileTypeIndex].type = backgroundTileTypeIndex;
backgroundTileTypeIndex++;
}
void loadTiles(SDL_Renderer *renderer) {
iterateSortedDir("./assets/tiles", (DirEntryCallback) registerTile, renderer);
// DIR *dir = opendir("./assets/tiles");
// if (dir) {
// struct dirent *entry;
// while ((entry = readdir(dir)) != NULL) {
// if (entry->d_name[0] == '.') {
// continue;
// }
// registerTile(entry->d_name, mainRenderer);
// }
// }
TileRegistry[0].breakTime = 0;
iterateSortedDir("./assets/backgrounds", (DirEntryCallback) registerBackgroundTile, renderer);
}
void setupTiles() {
TileRegistry[TYPE_AIR].breakTime = 0;
TileRegistry[TYPE_BELT].itemMoves = true;
for (uint16_t i = 0; i < ItemSlotCount; i++) {
TileRegistry[TYPE_BELT].outputLane[i] = true;
}
for (uint16_t l = 0; l < ItemSlotCount; l++) {
for (ItemType i = 0; i < itemRegistryIndex; i++) {
TileRegistry[TYPE_BELT].allowedInItems[l][i] = true;
}
}
for (ItemType i = 0; i < itemRegistryIndex; i++) {
if (FurnaceRecipes[i] != 0) {
TileRegistry[TYPE_FURNACE].allowedInItems[FURNACE_INPUT_SLOT][i] = true;
}
}
TileRegistry[TYPE_FURNACE].outputLane[FURNACE_OUTPUT_SLOT] = 1;
}
uint16_t getBreakTime(int type) {
@@ -92,6 +142,9 @@ void initTiles() {
screenRect.h);
tilesTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, screenRect.w,
screenRect.h);
backgroundTexture = 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);
}
@@ -99,10 +152,14 @@ void initTiles() {
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 tileSize = TILE_SIZE;
int minTileX = (playerRect.x / TILE_SIZE) - (DISPLAY_MAP_WIDTH / 2) - 1;
int maxTileX = (playerRect.x / TILE_SIZE) + (DISPLAY_MAP_WIDTH / 2) + 1;
int minTileY = (playerRect.y / TILE_SIZE) - (DISPLAY_MAP_HEIGHT / 2) - 1;
int maxTileY = (playerRect.y / TILE_SIZE) + (DISPLAY_MAP_HEIGHT / 2) + 1;
int scrollSpeed = 1; // pixels per step
int scrollDelay = 1; // frames between steps
@@ -110,42 +167,83 @@ void renderAllTiles(SDL_Renderer *renderer, SDL_Rect playerRect) {
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;
// --- Render background tiles ---
SDL_SetRenderTarget(renderer, backgroundTexture);
SDL_RenderClear(renderer);
for (int y = minTileY; y < maxTileY; y++) {
if (y < 0 || y >= MAP_HEIGHT) continue;
for (int x = minTileX; x < maxTileX; x++) {
if (x < 0 || x >= MAP_WIDTH) continue;
SDL_Rect dstRect = {
.x = x * TILE_SIZE,
.y = y * TILE_SIZE,
.w = TILE_SIZE,
.h = TILE_SIZE
};
adjustRect(&dstRect, playerRect);
BackgroundTile bt = backgroundMap[y][x];
SDL_Texture *tex = BackgroundTileRegistry[bt.type].texture;
if (tex != NULL) {
SDL_RenderCopy(renderer, tex, NULL, &dstRect);
}
}
}
SDL_SetRenderTarget(renderer, tilesTexture);
SDL_RenderClear(renderer);
for (int y = minTileY; y < maxTileY; y++) {
if (y < 0 || y >= MAP_HEIGHT) continue;
for (int x = minTileX; x < maxTileX; x++) {
if (x < 0 || x >= MAP_WIDTH) continue;
SDL_Rect dstRect = {
.x = x * TILE_SIZE,
.y = y * TILE_SIZE,
.w = TILE_SIZE,
.h = TILE_SIZE
};
adjustRect(&dstRect, playerRect);
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);
default: {
SDL_Texture *tex = TileRegistry[t.type].textures[t.direction];
if (tex == NULL) {
tex = TileRegistry[t.type].textures[ORIENT_LEFT];
}
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, itemsTexture);
SDL_RenderClear(renderer);
for (int y = minTileY; y < maxTileY; y++) {
if (y < 0 || y >= MAP_HEIGHT) continue;
for (int x = minTileX; x < maxTileX; x++) {
if (x < 0 || x >= MAP_WIDTH) continue;
Tile t = tileMap[y][x];
if (t.type == TYPE_BELT || itemViewing) {
for (uint8_t lane = 0; lane < ItemSlotCount; lane++) {
if (t.items[lane].type != 0) {
renderItem(t.items[lane], renderer, lane, playerRect);
}
}
}
}
}
SDL_SetRenderTarget(renderer, oldTarget);
}
void updateTiles() {
}

View File

@@ -5,15 +5,15 @@
#ifndef FACTORYGAME_TILE_H
#define FACTORYGAME_TILE_H
#include "belt.h"
#include "../util/util.h"
#include "../items/item.h"
//#include "../items/item.h"
#define MAP_WIDTH 600
#define MAP_HEIGHT 340
#define MAP_WIDTH 100
#define MAP_HEIGHT 100
#define DISPLAY_MAP_WIDTH 44
#define DISPLAY_MAP_HEIGHT 22
#define DISPLAY_MAP_WIDTH 60
#define DISPLAY_MAP_HEIGHT 31
#define TILE_SIZE 32
@@ -22,42 +22,108 @@
extern SDL_Texture *tilesTexture;
extern SDL_Texture *itemsTexture;
extern SDL_Texture *backgroundTexture;
extern int scrollFrame;
extern unsigned long beltFrames;
typedef struct {
uint16_t type;
#define ItemSlotCount 4
typedef enum BackgroundType {
BGType_WATER0,
BGType_WATER1,
BGType_GRASS0,
BGType_GRASS1,
BGType_GRASS2,
BGType_GRASS3,
BGType_GRASS4,
BGType_GRASS5,
BGType_GRASS6,
BGType_GRASS7,
BGType_GRASS_FLOWER0,
BGType_GRASS_FLOWER1,
BGType_GRASS_FLOWER2,
BGType_GRASS_FLOWER3,
BGType_SAND0,
BGType_SAND1,
BGType_SAND2,
BGType_SAND3,
BGType_SAND4,
BGType_SAND5,
BGType_SAND6,
BGType_SAND7,
BGType_TILES0,
BGType_TILES1,
BGType_TILES2,
BGType_TILES3,
BGType_COBBLE0,
BGType_COBBLE1,
BGType_COBBLE2,
BGType_COBBLE3,
BGType_PLATINUM_ORE,
BGType_GOLD_ORE,
BGType_SILVER_ORE,
BGType_IRON_ORE,
BGType_END
} BackgroundType;
typedef struct TileTypeReg {
ItemType type;
char name[20];
SDL_Texture *textures[ORIENT_DIRECTION_COUNT];
SDL_Rect atlasRects[ORIENT_DIRECTION_COUNT];
uint16_t breakTime;
} TileType;
bool itemMoves;
bool allowedInItems[ItemSlotCount][ITEMREGISTRY_SIZE];
bool outputLane[ItemSlotCount];
} TileTypeReg;
#define TILEREGISTRY_SIZE 512
typedef struct BackgroundTileType {
ItemType type;
char name[20];
SDL_Texture *texture;
SDL_Rect atlasRect;
} BackgroundTileType;
extern TileType TileRegistry[TILEREGISTRY_SIZE];
typedef struct BackgroundTile {
BackgroundType type;
} BackgroundTile;
#define TYPE_AIR 0
#define TYPE_BELT 2
#define TILEREGISTRY_SIZE 64
extern BackgroundTileType BackgroundTileRegistry[TILEREGISTRY_SIZE];
extern TileTypeReg TileRegistry[TILEREGISTRY_SIZE];
void renderAllTiles(SDL_Renderer *renderer, SDL_Rect playerRect);
typedef struct {
void updateTiles();
typedef struct Tile {
OrientDirection direction;
uint16_t type;
int frameOffset;
ItemOnBelt items[2];
ItemType type;
int miscVal;
ItemOnBelt items[ItemSlotCount];
uint16_t audioCh;
int x;
int y;
} Tile;
extern Tile tileMap[MAP_HEIGHT][MAP_WIDTH];
extern BackgroundTile backgroundMap[MAP_HEIGHT][MAP_WIDTH];
void setupTiles();
void generateTestMap();
void loadTiles(SDL_Renderer *renderer);
extern uint16_t tileTypeIndex;
extern uint16_t backgroundTileTypeIndex;
uint16_t getBreakTime(int type);

13
tiles/tilecallbacks.c Normal file
View File

@@ -0,0 +1,13 @@
//
// Created by bruno on 1.6.2025.
//
#include "tilecallbacks.h"
#include "furnace.h"
const UpdateTileCallback ItemTileCallbacks[TILEREGISTRY_SIZE] = {
[TYPE_AIR] = NULL,
[TYPE_BLOCK] = NULL,
[TYPE_BELT] = updateBelt,
[TYPE_FURNACE] = updateFurnace
};

14
tiles/tilecallbacks.h Normal file
View File

@@ -0,0 +1,14 @@
//
// Created by bruno on 1.6.2025.
//
#ifndef FACTORYGAME_TILECALLBACKS_H
#define FACTORYGAME_TILECALLBACKS_H
#include "tile.h"
typedef void (*UpdateTileCallback)(struct Tile *tile);
extern const UpdateTileCallback ItemTileCallbacks[];
#endif //FACTORYGAME_TILECALLBACKS_H