diff --git a/assets/backgrounds/00_water_00.png b/assets/backgrounds/00_water_00.png new file mode 100644 index 0000000..335d90a Binary files /dev/null and b/assets/backgrounds/00_water_00.png differ diff --git a/assets/backgrounds/00_water_01.png b/assets/backgrounds/00_water_01.png new file mode 100644 index 0000000..663a99f Binary files /dev/null and b/assets/backgrounds/00_water_01.png differ diff --git a/assets/backgrounds/00_water_02.png b/assets/backgrounds/00_water_02.png new file mode 100644 index 0000000..b2b68a2 Binary files /dev/null and b/assets/backgrounds/00_water_02.png differ diff --git a/assets/backgrounds/00_water_03.png b/assets/backgrounds/00_water_03.png new file mode 100644 index 0000000..016d127 Binary files /dev/null and b/assets/backgrounds/00_water_03.png differ diff --git a/assets/backgrounds/00_water_04.png b/assets/backgrounds/00_water_04.png new file mode 100644 index 0000000..c9a3a80 Binary files /dev/null and b/assets/backgrounds/00_water_04.png differ diff --git a/assets/backgrounds/00_water_05.png b/assets/backgrounds/00_water_05.png new file mode 100644 index 0000000..b4f72ce Binary files /dev/null and b/assets/backgrounds/00_water_05.png differ diff --git a/assets/backgrounds/00_water_06.png b/assets/backgrounds/00_water_06.png new file mode 100644 index 0000000..66c0c89 Binary files /dev/null and b/assets/backgrounds/00_water_06.png differ diff --git a/assets/backgrounds/00_water_07.png b/assets/backgrounds/00_water_07.png new file mode 100644 index 0000000..fbb5828 Binary files /dev/null and b/assets/backgrounds/00_water_07.png differ diff --git a/assets/backgrounds/00_water_08.png b/assets/backgrounds/00_water_08.png new file mode 100644 index 0000000..5e268df Binary files /dev/null and b/assets/backgrounds/00_water_08.png differ diff --git a/assets/backgrounds/00_water_09.png b/assets/backgrounds/00_water_09.png new file mode 100644 index 0000000..c068332 Binary files /dev/null and b/assets/backgrounds/00_water_09.png differ diff --git a/assets/backgrounds/00_water_10.png b/assets/backgrounds/00_water_10.png new file mode 100644 index 0000000..0bd3844 Binary files /dev/null and b/assets/backgrounds/00_water_10.png differ diff --git a/assets/backgrounds/00_water_11.png b/assets/backgrounds/00_water_11.png new file mode 100644 index 0000000..04255de Binary files /dev/null and b/assets/backgrounds/00_water_11.png differ diff --git a/assets/backgrounds/00water.png b/assets/backgrounds/00water.png deleted file mode 100644 index db6fec3..0000000 Binary files a/assets/backgrounds/00water.png and /dev/null differ diff --git a/assets/backgrounds/01_water_00.png b/assets/backgrounds/01_water_00.png new file mode 100644 index 0000000..3fb6d19 Binary files /dev/null and b/assets/backgrounds/01_water_00.png differ diff --git a/assets/backgrounds/01_water_01.png b/assets/backgrounds/01_water_01.png new file mode 100644 index 0000000..2d6d96c Binary files /dev/null and b/assets/backgrounds/01_water_01.png differ diff --git a/assets/backgrounds/01_water_02.png b/assets/backgrounds/01_water_02.png new file mode 100644 index 0000000..d6feb78 Binary files /dev/null and b/assets/backgrounds/01_water_02.png differ diff --git a/assets/backgrounds/01_water_03.png b/assets/backgrounds/01_water_03.png new file mode 100644 index 0000000..8774d19 Binary files /dev/null and b/assets/backgrounds/01_water_03.png differ diff --git a/assets/backgrounds/01_water_04.png b/assets/backgrounds/01_water_04.png new file mode 100644 index 0000000..6510abf Binary files /dev/null and b/assets/backgrounds/01_water_04.png differ diff --git a/assets/backgrounds/01_water_05.png b/assets/backgrounds/01_water_05.png new file mode 100644 index 0000000..c8e5b0e Binary files /dev/null and b/assets/backgrounds/01_water_05.png differ diff --git a/assets/backgrounds/01_water_06.png b/assets/backgrounds/01_water_06.png new file mode 100644 index 0000000..bf251e5 Binary files /dev/null and b/assets/backgrounds/01_water_06.png differ diff --git a/assets/backgrounds/01_water_07.png b/assets/backgrounds/01_water_07.png new file mode 100644 index 0000000..08d2bc3 Binary files /dev/null and b/assets/backgrounds/01_water_07.png differ diff --git a/assets/backgrounds/01_water_08.png b/assets/backgrounds/01_water_08.png new file mode 100644 index 0000000..d1a4828 Binary files /dev/null and b/assets/backgrounds/01_water_08.png differ diff --git a/assets/backgrounds/01_water_09.png b/assets/backgrounds/01_water_09.png new file mode 100644 index 0000000..8d5fdc1 Binary files /dev/null and b/assets/backgrounds/01_water_09.png differ diff --git a/assets/backgrounds/01_water_10.png b/assets/backgrounds/01_water_10.png new file mode 100644 index 0000000..7bd7f02 Binary files /dev/null and b/assets/backgrounds/01_water_10.png differ diff --git a/assets/backgrounds/01_water_11.png b/assets/backgrounds/01_water_11.png new file mode 100644 index 0000000..34ba34d Binary files /dev/null and b/assets/backgrounds/01_water_11.png differ diff --git a/assets/backgrounds/01water.png b/assets/backgrounds/01water.png deleted file mode 100644 index df8c4d1..0000000 Binary files a/assets/backgrounds/01water.png and /dev/null differ diff --git a/assets/backgrounds/09grass.png b/assets/backgrounds/02_grass_00.png similarity index 100% rename from assets/backgrounds/09grass.png rename to assets/backgrounds/02_grass_00.png diff --git a/assets/backgrounds/08grass.png b/assets/backgrounds/02_grass_01.png similarity index 100% rename from assets/backgrounds/08grass.png rename to assets/backgrounds/02_grass_01.png diff --git a/assets/backgrounds/10grass.png b/assets/backgrounds/02_grass_02.png similarity index 100% rename from assets/backgrounds/10grass.png rename to assets/backgrounds/02_grass_02.png diff --git a/assets/backgrounds/07grass.png b/assets/backgrounds/02_grass_02s.png similarity index 100% rename from assets/backgrounds/07grass.png rename to assets/backgrounds/02_grass_02s.png diff --git a/assets/backgrounds/06grass.png b/assets/backgrounds/02_grass_03.png similarity index 100% rename from assets/backgrounds/06grass.png rename to assets/backgrounds/02_grass_03.png diff --git a/assets/backgrounds/13grass.png b/assets/backgrounds/03_grass_00.png similarity index 100% rename from assets/backgrounds/13grass.png rename to assets/backgrounds/03_grass_00.png diff --git a/assets/backgrounds/12grass.png b/assets/backgrounds/03_grass_01.png similarity index 100% rename from assets/backgrounds/12grass.png rename to assets/backgrounds/03_grass_01.png diff --git a/assets/backgrounds/11grass.png b/assets/backgrounds/03_grass_02.png similarity index 100% rename from assets/backgrounds/11grass.png rename to assets/backgrounds/03_grass_02.png diff --git a/assets/backgrounds/05grass.png b/assets/backgrounds/04_grass_00.png similarity index 100% rename from assets/backgrounds/05grass.png rename to assets/backgrounds/04_grass_00.png diff --git a/assets/backgrounds/02grass.png b/assets/backgrounds/05_grass_00.png similarity index 100% rename from assets/backgrounds/02grass.png rename to assets/backgrounds/05_grass_00.png diff --git a/assets/backgrounds/03grass.png b/assets/backgrounds/06_grass_00.png similarity index 100% rename from assets/backgrounds/03grass.png rename to assets/backgrounds/06_grass_00.png diff --git a/assets/backgrounds/04grass.png b/assets/backgrounds/07_grass_00.png similarity index 100% rename from assets/backgrounds/04grass.png rename to assets/backgrounds/07_grass_00.png diff --git a/assets/backgrounds/21sand.png b/assets/backgrounds/08_sand_00.png similarity index 100% rename from assets/backgrounds/21sand.png rename to assets/backgrounds/08_sand_00.png diff --git a/assets/backgrounds/20sand.png b/assets/backgrounds/09_sand_00.png similarity index 100% rename from assets/backgrounds/20sand.png rename to assets/backgrounds/09_sand_00.png diff --git a/assets/backgrounds/19sand.png b/assets/backgrounds/10_sand_00.png similarity index 100% rename from assets/backgrounds/19sand.png rename to assets/backgrounds/10_sand_00.png diff --git a/assets/backgrounds/18sand.png b/assets/backgrounds/11_sand_00.png similarity index 100% rename from assets/backgrounds/18sand.png rename to assets/backgrounds/11_sand_00.png diff --git a/assets/backgrounds/17sand.png b/assets/backgrounds/12_sand_00.png similarity index 100% rename from assets/backgrounds/17sand.png rename to assets/backgrounds/12_sand_00.png diff --git a/assets/backgrounds/16sand.png b/assets/backgrounds/13_sand_00.png similarity index 100% rename from assets/backgrounds/16sand.png rename to assets/backgrounds/13_sand_00.png diff --git a/assets/backgrounds/15sand.png b/assets/backgrounds/14_sand_00.png similarity index 100% rename from assets/backgrounds/15sand.png rename to assets/backgrounds/14_sand_00.png diff --git a/assets/backgrounds/14sand.png b/assets/backgrounds/15_sand_00.png similarity index 100% rename from assets/backgrounds/14sand.png rename to assets/backgrounds/15_sand_00.png diff --git a/assets/backgrounds/23tiles.png b/assets/backgrounds/16_tiles_00.png similarity index 100% rename from assets/backgrounds/23tiles.png rename to assets/backgrounds/16_tiles_00.png diff --git a/assets/backgrounds/22tiles.png b/assets/backgrounds/17_tiles_00.png similarity index 100% rename from assets/backgrounds/22tiles.png rename to assets/backgrounds/17_tiles_00.png diff --git a/assets/backgrounds/24tiles.png b/assets/backgrounds/18_tiles_00.png similarity index 100% rename from assets/backgrounds/24tiles.png rename to assets/backgrounds/18_tiles_00.png diff --git a/assets/backgrounds/25tiles.png b/assets/backgrounds/19_tiles_00.png similarity index 100% rename from assets/backgrounds/25tiles.png rename to assets/backgrounds/19_tiles_00.png diff --git a/assets/backgrounds/27cobble.png b/assets/backgrounds/20_cobble_00.png similarity index 100% rename from assets/backgrounds/27cobble.png rename to assets/backgrounds/20_cobble_00.png diff --git a/assets/backgrounds/26cobble.png b/assets/backgrounds/21_cobble_00.png similarity index 100% rename from assets/backgrounds/26cobble.png rename to assets/backgrounds/21_cobble_00.png diff --git a/assets/backgrounds/28cobble.png b/assets/backgrounds/22_cobble_00.png similarity index 100% rename from assets/backgrounds/28cobble.png rename to assets/backgrounds/22_cobble_00.png diff --git a/assets/backgrounds/29cobble.png b/assets/backgrounds/23_cobble_00.png similarity index 100% rename from assets/backgrounds/29cobble.png rename to assets/backgrounds/23_cobble_00.png diff --git a/assets/backgrounds/33resource.png b/assets/backgrounds/24_resource_00.png similarity index 100% rename from assets/backgrounds/33resource.png rename to assets/backgrounds/24_resource_00.png diff --git a/assets/backgrounds/32resource.png b/assets/backgrounds/25_resource_00.png similarity index 100% rename from assets/backgrounds/32resource.png rename to assets/backgrounds/25_resource_00.png diff --git a/assets/backgrounds/31resource.png b/assets/backgrounds/26_resource_00.png similarity index 100% rename from assets/backgrounds/31resource.png rename to assets/backgrounds/26_resource_00.png diff --git a/assets/backgrounds/30resource.png b/assets/backgrounds/27_resource_00.png similarity index 100% rename from assets/backgrounds/30resource.png rename to assets/backgrounds/27_resource_00.png diff --git a/assets/items/00iron_ore.png b/assets/items/00-iron_ore-00.png similarity index 100% rename from assets/items/00iron_ore.png rename to assets/items/00-iron_ore-00.png diff --git a/assets/items/01silver_ore.png b/assets/items/01-silver_ore-00.png similarity index 100% rename from assets/items/01silver_ore.png rename to assets/items/01-silver_ore-00.png diff --git a/assets/items/02gold_ore.png b/assets/items/02-gold_ore-00.png similarity index 100% rename from assets/items/02gold_ore.png rename to assets/items/02-gold_ore-00.png diff --git a/assets/items/03platinum_ore.png b/assets/items/03-platinum_ore-00.png similarity index 100% rename from assets/items/03platinum_ore.png rename to assets/items/03-platinum_ore-00.png diff --git a/assets/items/04iron_ingot.png b/assets/items/04-iron_ingot-00.png similarity index 100% rename from assets/items/04iron_ingot.png rename to assets/items/04-iron_ingot-00.png diff --git a/assets/items/05gold_ingot.png b/assets/items/05-gold_ingot-00.png similarity index 100% rename from assets/items/05gold_ingot.png rename to assets/items/05-gold_ingot-00.png diff --git a/assets/items/06platinum_ingot.png b/assets/items/06-platinum_ingot-00.png similarity index 100% rename from assets/items/06platinum_ingot.png rename to assets/items/06-platinum_ingot-00.png diff --git a/assets/items/07silver_ingot.png b/assets/items/07-silver_ingot-00.png similarity index 100% rename from assets/items/07silver_ingot.png rename to assets/items/07-silver_ingot-00.png diff --git a/assets/items/08log.png b/assets/items/08-log-00.png similarity index 100% rename from assets/items/08log.png rename to assets/items/08-log-00.png diff --git a/assets/tiles/0air.png b/assets/tiles/00_air_00.png similarity index 100% rename from assets/tiles/0air.png rename to assets/tiles/00_air_00.png diff --git a/assets/tiles/1blanker.png b/assets/tiles/01_blanker_00.png similarity index 100% rename from assets/tiles/1blanker.png rename to assets/tiles/01_blanker_00.png diff --git a/assets/tiles/2dopravnik.png b/assets/tiles/02_dopravnik_00.png similarity index 100% rename from assets/tiles/2dopravnik.png rename to assets/tiles/02_dopravnik_00.png diff --git a/assets/tiles/03_furnace_00.png b/assets/tiles/03_furnace_00.png new file mode 100644 index 0000000..f944de7 Binary files /dev/null and b/assets/tiles/03_furnace_00.png differ diff --git a/assets/tiles/3furnace.png b/assets/tiles/03_furnace_01.png similarity index 100% rename from assets/tiles/3furnace.png rename to assets/tiles/03_furnace_01.png diff --git a/assets/tiles/03_furnace_02.png b/assets/tiles/03_furnace_02.png new file mode 100644 index 0000000..99e24ae Binary files /dev/null and b/assets/tiles/03_furnace_02.png differ diff --git a/assets/tiles/03_furnace_03.png b/assets/tiles/03_furnace_03.png new file mode 100644 index 0000000..872f487 Binary files /dev/null and b/assets/tiles/03_furnace_03.png differ diff --git a/assets/tiles/03_furnace_04.png b/assets/tiles/03_furnace_04.png new file mode 100644 index 0000000..970416e Binary files /dev/null and b/assets/tiles/03_furnace_04.png differ diff --git a/assets/tiles/03_furnace_05.png b/assets/tiles/03_furnace_05.png new file mode 100644 index 0000000..4fc0238 Binary files /dev/null and b/assets/tiles/03_furnace_05.png differ diff --git a/assets/tiles/03_furnace_06.png b/assets/tiles/03_furnace_06.png new file mode 100644 index 0000000..e4bd2a9 Binary files /dev/null and b/assets/tiles/03_furnace_06.png differ diff --git a/assets/tiles/4miner.png b/assets/tiles/04_miner_00.png similarity index 100% rename from assets/tiles/4miner.png rename to assets/tiles/04_miner_00.png diff --git a/assets/tiles/04_miner_01.png b/assets/tiles/04_miner_01.png new file mode 100644 index 0000000..6e68be0 Binary files /dev/null and b/assets/tiles/04_miner_01.png differ diff --git a/assets/tiles/04_miner_02.png b/assets/tiles/04_miner_02.png new file mode 100644 index 0000000..98c4e9a Binary files /dev/null and b/assets/tiles/04_miner_02.png differ diff --git a/assets/tiles/04_miner_03.png b/assets/tiles/04_miner_03.png new file mode 100644 index 0000000..5d7d1a8 Binary files /dev/null and b/assets/tiles/04_miner_03.png differ diff --git a/assets/tiles/04_miner_04.png b/assets/tiles/04_miner_04.png new file mode 100644 index 0000000..779ed20 Binary files /dev/null and b/assets/tiles/04_miner_04.png differ diff --git a/assets/tiles/04_miner_05.png b/assets/tiles/04_miner_05.png new file mode 100644 index 0000000..c80d002 Binary files /dev/null and b/assets/tiles/04_miner_05.png differ diff --git a/assets/tiles/04_miner_06.png b/assets/tiles/04_miner_06.png new file mode 100644 index 0000000..c7b966f Binary files /dev/null and b/assets/tiles/04_miner_06.png differ diff --git a/assets/tiles/04_miner_07.png b/assets/tiles/04_miner_07.png new file mode 100644 index 0000000..100482d Binary files /dev/null and b/assets/tiles/04_miner_07.png differ diff --git a/items/item.c b/items/item.c index 1f01d9b..7387667 100644 --- a/items/item.c +++ b/items/item.c @@ -117,29 +117,6 @@ void updateItems() { } } - -void registerItem(char name[20], SDL_Renderer *renderer) { - const char *dot = strchr(name, '.'); - memcpy(ItemRegistry[itemRegistryIndex].name, name, dot - name); - char texturePath[80]; - snprintf(texturePath, 80, "./assets/items/%s", name); - ItemRegistry[itemRegistryIndex].texture[ORIENT_LEFT] = IMG_LoadTexture(renderer, texturePath); - SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].texture[0], SDL_BLENDMODE_BLEND); - ItemRegistry[itemRegistryIndex].textureOnBelt[ORIENT_LEFT] = ScaleTexture(renderer, - ItemRegistry[itemRegistryIndex].texture[ORIENT_LEFT], - TILE_SIZE / 2, TILE_SIZE / 2); - SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].textureOnBelt[ORIENT_LEFT], SDL_BLENDMODE_BLEND); - ItemRegistry[itemRegistryIndex].atlasRects[ORIENT_LEFT] = allocate_32x32( - ItemRegistry[itemRegistryIndex].texture[ORIENT_LEFT], renderer); - ItemRegistry[itemRegistryIndex].atlasRectsOnBelt[ORIENT_LEFT] = allocate_16x16( - ItemRegistry[itemRegistryIndex].textureOnBelt[ORIENT_LEFT], renderer); - ItemRegistry[itemRegistryIndex].type = itemRegistryIndex; - ItemRegistry[itemRegistryIndex].isTile = false; - ItemRegistry[itemRegistryIndex].miscVal = 60; - - itemRegistryIndex++; -} - // easing function: cosine ease‐in‐out //static float ease_in_out(float t) { // if (t < -1.0f) t = -1.0f; @@ -297,7 +274,11 @@ void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane, SDL_Rect play SDL_RenderFillRect(renderer, &rectA); } //SDL_RenderCopyx(renderer, ItemRegistry[item.type].textureOnBelt[ORIENT_LEFT], NULL, &rect); - SDL_RenderCopy(renderer, atlasTexture, &ItemRegistry[item.type].atlasRectsOnBelt[ORIENT_LEFT], &rect); + SDL_RenderCopy(renderer, atlasTexture, + &ItemRegistry[item.type].beltAnimation.atlasRects[ORIENT_LEFT][ + (animationStep / ItemRegistry[item.type].beltAnimation.divisor) % + ItemRegistry[item.type].beltAnimation.frameCount], + &rect); if (debugMode) { renderText(renderer, fonts[3], tempStr, rectA.x, rectA.y); @@ -312,29 +293,102 @@ void putItem(int x, int y, ItemType itemType, uint8_t lane) { } void loadItems(SDL_Renderer *renderer) { - + // Load tile-based items for (int i = 0; i < tileTypeIndex; i++) { TileTypeReg tile = TileRegistry[i]; - strcpy(ItemRegistry[itemRegistryIndex].name, tile.name); - memcpy(ItemRegistry[itemRegistryIndex].texture, tile.textures, sizeof(tile.textures)); - memcpy(ItemRegistry[itemRegistryIndex].atlasRects, tile.atlasRects, sizeof(tile.atlasRects)); - for (int a = 0; a < ORIENT_DIRECTION_COUNT; a++) { - SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].texture[a], SDL_BLENDMODE_BLEND); - ItemRegistry[itemRegistryIndex].textureOnBelt[a] = ScaleTexture(renderer, tile.textures[a], - TILE_SIZE / 2, TILE_SIZE / 2); - ItemRegistry[itemRegistryIndex].atlasRectsOnBelt[a] = allocate_16x16( - ItemRegistry[itemRegistryIndex].textureOnBelt[a], renderer); - SDL_SetTextureBlendMode(ItemRegistry[itemRegistryIndex].textureOnBelt[a], SDL_BLENDMODE_BLEND); + Item *item = &ItemRegistry[itemRegistryIndex]; + strcpy(item->name, tile.name); + memcpy(&item->animation, &tile.animation, sizeof(tile.animation)); + + for (int frame = 0; frame < item->animation.frameCount; frame++) { + for (int a = 0; a < ORIENT_DIRECTION_COUNT; a++) { + SDL_SetTextureBlendMode(item->animation.textures[a][frame], SDL_BLENDMODE_BLEND); + item->beltAnimation.textures[a][frame] = ScaleTexture(renderer, tile.animation.textures[a][frame], + TILE_SIZE / 2, TILE_SIZE / 2); + item->beltAnimation.atlasRects[a][frame] = allocate_16x16(item->beltAnimation.textures[a][frame], + renderer); + if (frame + 1 > item->beltAnimation.frameCount) { + item->beltAnimation.frameCount = frame + 1; + } + SDL_SetTextureBlendMode(item->beltAnimation.textures[a][frame], SDL_BLENDMODE_BLEND); + } } - ItemRegistry[itemRegistryIndex].type = itemRegistryIndex; - ItemRegistry[itemRegistryIndex].isTile = true; + + item->type = itemRegistryIndex; + item->isTile = true; + item->animation.divisor = 1; + item->beltAnimation.divisor = 1; itemRegistryIndex++; } - + // Skip ahead to avoid overlap (tile items use lower indices) itemRegistryIndex = ITEMREGISTRY_SIZE / 2; - iterateSortedDir("./assets/items", (DirEntryCallback) registerItem, renderer); -} \ No newline at end of file + // Load sprite-based items with animations + DIR *dir = opendir("./assets/items"); + if (!dir) { + perror("Failed to open item asset folder"); + return; + } + + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + if (!strstr(entry->d_name, ".png")) continue; + + int frame, indexItem; + char name[64]; + + if (sscanf(entry->d_name, "%d-%20[^-]-%d.png", &indexItem, name, &frame) == 3) { + // Success: you now have index, fname, and frame + } else { + fprintf(stderr, "Invalid format: %s\n", entry->d_name); + } + indexItem += ITEMREGISTRY_SIZE / 2; + + Item *item; + item = &ItemRegistry[indexItem]; + memset(item, 0, sizeof(Item)); + strcpy(item->name, name); + item->type = indexItem; + item->isTile = false; + item->miscVal = 60; + item->animation.divisor = 1; + item->beltAnimation.divisor = 1; + + // Load the texture + char path[128]; + snprintf(path, sizeof(path), "./assets/items/%s", entry->d_name); + SDL_Texture *tex = IMG_LoadTexture(renderer, path); + if (!tex) { + fprintf(stderr, "Failed to load texture %s: %s\n", path, IMG_GetError()); + continue; + } + + SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND); + SDL_Texture *beltTex = ScaleTexture(renderer, tex, TILE_SIZE / 2, TILE_SIZE / 2); + SDL_SetTextureBlendMode(beltTex, SDL_BLENDMODE_BLEND); + + SDL_Rect mainRect = allocate_32x32(tex, renderer); + SDL_Rect beltRect = allocate_16x16(beltTex, renderer); + // Assign to all orientations + for (int o = 0; o < ORIENT_DIRECTION_COUNT; o++) { + item->animation.textures[o][frame] = tex; + item->beltAnimation.textures[o][frame] = beltTex; + item->animation.atlasRects[o][frame] = mainRect; + item->beltAnimation.atlasRects[o][frame] = beltRect; + if (frame + 1 > item->animation.frameCount) { + item->animation.frameCount = frame + 1; + item->beltAnimation.frameCount = frame + 1; + } + + } + item->animation.divisor = 1; + if (indexItem + 1 > itemRegistryIndex) { + itemRegistryIndex = indexItem + 1; + } + } + + closedir(dir); +} diff --git a/items/item.h b/items/item.h index d963ce3..ad4892f 100644 --- a/items/item.h +++ b/items/item.h @@ -42,10 +42,8 @@ typedef struct Item { ItemType type; char name[20]; uint16_t miscVal; - SDL_Texture * texture[ORIENT_DIRECTION_COUNT]; - SDL_Texture * textureOnBelt[ORIENT_DIRECTION_COUNT]; - SDL_Rect atlasRects[ORIENT_DIRECTION_COUNT]; - SDL_Rect atlasRectsOnBelt[ORIENT_DIRECTION_COUNT]; + OrientedAnimation animation; + OrientedAnimation beltAnimation; } Item; diff --git a/main.c b/main.c index 994c735..db90671 100644 --- a/main.c +++ b/main.c @@ -139,6 +139,7 @@ int init() { initAtlas(mainRenderer); + loadBackgroundTiles(mainRenderer); loadTiles(mainRenderer); loadItems(mainRenderer); setupTiles(); @@ -506,6 +507,9 @@ void processKeyboardHeld() { setActivePlayerSlot(&player, 0); } } + if (keyboardState[SDL_SCANCODE_F9]) { + player.inventory.slotCounts[player.inventory.activeSlotIndex]++; + } if (keyboardState[SDL_SCANCODE_Y]) { if (player.cursor.canReach && player.cursor.targetTile->type == TYPE_BELT && player.inventory.slotCounts[player.inventory.activeSlotIndex] > 0) { @@ -586,6 +590,7 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char *args[]) updateItems(); updatePlayer(&player); updateTiles(); + animationStep++; status = render(); if (status) { return status; @@ -655,15 +660,15 @@ void genInitMap() { // [Same as your original terrain generation logic...] BackgroundType baseType; if (terrain < 0.30) { - baseType = (humidity < 0.5) ? BGType_WATER0 : BGType_WATER1; + baseType = (humidity < 0.5) ? BGType_WATER_SHALLOW : BGType_WATER_DEEP; } else if (terrain < 0.35) { if (humidity < 0.3) baseType = BGType_SAND4; else if (humidity < 0.6) baseType = BGType_SAND2; else baseType = BGType_SAND7; } else if (terrain < 0.7) { double grassVal = (terrain - 0.35) / (0.70 - 0.35); - int idx = (int) (grassVal * 8.0); - if (idx >= 8) idx = 7; + int idx = (int) (grassVal * 3.0); + if (idx >= 4) idx = 3; if (humidity > 0.6 && ((rand() & 0xFF) < 10)) { int flowerIdx = rand() % 4; baseType = (BackgroundType) (BGType_GRASS_FLOWER0 + flowerIdx); @@ -679,7 +684,7 @@ void genInitMap() { } BackgroundType finalType = baseType; - if (baseType != BGType_WATER0 && baseType != BGType_WATER1) { + if (baseType != BGType_WATER_SHALLOW && baseType != BGType_WATER_DEEP) { if (oreNrm > 0.86) { double sub = (oreNrm - 0.86) / (1.0 - 0.86); if (sub < 0.25) finalType = BGType_PLATINUM_ORE; diff --git a/player/player.c b/player/player.c index 6b74a74..a9109fc 100644 --- a/player/player.c +++ b/player/player.c @@ -179,9 +179,9 @@ void renderPlayer(Player *plr) { plr->cursor.heldItemRect.x = plr->cursor.windowX; plr->cursor.heldItemRect.y = plr->cursor.windowY; //itemTex = ItemRegistry[itemIndex].textureOnBelt[plr->cursor.direction]; - SDL_Rect itemAtlasRect = ItemRegistry[itemIndex].atlasRects[plr->cursor.direction]; + SDL_Rect itemAtlasRect = ItemRegistry[itemIndex].animation.atlasRects[plr->cursor.direction][(animationStep / ItemRegistry[itemIndex].animation.divisor) % ItemRegistry[itemIndex].animation.frameCount]; if (itemAtlasRect.w == 0 || itemAtlasRect.h == 0) { - itemAtlasRect = ItemRegistry[itemIndex].atlasRects[ORIENT_LEFT]; + itemAtlasRect = ItemRegistry[itemIndex].animation.atlasRects[ORIENT_LEFT][(animationStep / ItemRegistry[itemIndex].animation.divisor) % ItemRegistry[itemIndex].animation.frameCount]; } if (itemAtlasRect.w != 0 && itemAtlasRect.h != 0) { @@ -197,8 +197,10 @@ void renderPlayer(Player *plr) { // } // SDL_RenderCopy(mainRenderer, itemTex, NULL, // &plr->cursor.heldItemRect); + char nameItem[80]; + snprintf(nameItem, 80, "%s\n%s", ItemRegistry[itemIndex].name, OrientStrings[plr->cursor.direction]); SDL_RenderCopy(mainRenderer, atlasTexture, &itemAtlasRect, &plr->cursor.heldItemRect); - renderText(mainRenderer, fonts[2], ItemRegistry[itemIndex].name, plr->cursor.heldItemRect.x, + renderText(mainRenderer, fonts[2], nameItem, plr->cursor.heldItemRect.x, plr->cursor.heldItemRect.y - (fonts[2].size * 3 / 2)); } } @@ -223,9 +225,12 @@ void renderPlayer(Player *plr) { SDL_SetTextureBlendMode(atlasTexture, SDL_BLENDMODE_ADD); for (ItemType i = 0; i < ITEMREGISTRY_SIZE; i++) { - SDL_Rect itemAtlasRectd = ItemRegistry[i].atlasRects[plr->cursor.direction]; + if (ItemRegistry[i].name[0] == 0x00) { + continue; + } + SDL_Rect itemAtlasRectd = ItemRegistry[i].animation.atlasRects[plr->cursor.direction][(animationStep / ItemRegistry[i].animation.divisor) % ItemRegistry[i].animation.frameCount]; if (itemAtlasRectd.w == 0 || itemAtlasRectd.h == 0) { - itemAtlasRectd = ItemRegistry[i].atlasRects[ORIENT_LEFT]; + itemAtlasRectd = ItemRegistry[i].animation.atlasRects[ORIENT_LEFT][(animationStep / ItemRegistry[i].animation.divisor) % ItemRegistry[i].animation.frameCount]; } if (itemAtlasRectd.w != 0 && itemAtlasRectd.h != 0) { // if (plr->inventory.slotCounts[i] <= 0) { diff --git a/tiles/belt.c b/tiles/belt.c index ccd4165..1b09468 100644 --- a/tiles/belt.c +++ b/tiles/belt.c @@ -10,63 +10,97 @@ #include "../items/item.h" #include "../util/atlas.h" +void generateBeltFrames(SDL_Renderer *renderer) { + SDL_Texture *baseTexture = TileRegistry[TYPE_BELT].animation.textures[ORIENT_LEFT][0]; // Base belt tile + SDL_Texture *oldTarget = SDL_GetRenderTarget(renderer); + const int frameCount = TILE_SIZE; // 32 frames, 1px per frame = full seamless loop + + for (OrientDirection dir = ORIENT_LEFT_DOWN; dir < ORIENT_DIRECTION_COUNT; dir++) { + double angle = 0.0; + bool isHorizontal = true; + bool reverse = false; + + switch (dir) { + case ORIENT_LEFT: + angle = 0; + isHorizontal = true; + reverse = false; + break; + case ORIENT_UP: + angle = 90; + isHorizontal = false; + reverse = false; + break; + case ORIENT_RIGHT: + angle = 180; + isHorizontal = true; + reverse = true; + break; + case ORIENT_DOWN: + angle = 270; + isHorizontal = false; + reverse = true; + break; + default: + continue; // skip diagonals or unsupported directions + } + + // Step 1: Rotate the tile once + SDL_Texture *rotated = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_TARGET, TILE_SIZE, TILE_SIZE); + SDL_SetTextureBlendMode(rotated, SDL_BLENDMODE_BLEND); + SDL_SetRenderTarget(renderer, rotated); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); + + SDL_Rect full = {0, 0, TILE_SIZE, TILE_SIZE}; + SDL_RenderCopyEx(renderer, baseTexture, NULL, &full, angle, NULL, SDL_FLIP_NONE); + + // Step 2: For each frame, render 2 rotated tiles with wrapping offset + for (int f = 0; f < frameCount; f++) { + SDL_Texture *frame = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_TARGET, TILE_SIZE, TILE_SIZE); + SDL_SetTextureBlendMode(frame, SDL_BLENDMODE_BLEND); + SDL_SetRenderTarget(renderer, frame); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); + + int offset = reverse ? (TILE_SIZE - f) % TILE_SIZE : f; + + SDL_Rect dst1, dst2; + if (isHorizontal) { + dst1 = (SDL_Rect) {-offset, 0, TILE_SIZE, TILE_SIZE}; + dst2 = (SDL_Rect) {TILE_SIZE - offset, 0, TILE_SIZE, TILE_SIZE}; + } else { + dst1 = (SDL_Rect) {0, -offset, TILE_SIZE, TILE_SIZE}; + dst2 = (SDL_Rect) {0, TILE_SIZE - offset, TILE_SIZE, TILE_SIZE}; + } + + SDL_RenderCopy(renderer, rotated, NULL, &dst1); + SDL_RenderCopy(renderer, rotated, NULL, &dst2); + + TileRegistry[TYPE_BELT].animation.textures[dir][f] = frame; + TileRegistry[TYPE_BELT].animation.atlasRects[dir][f] = allocate_32x32(frame, renderer); + } + + SDL_DestroyTexture(rotated); + TileRegistry[TYPE_BELT].animation.frameCount = frameCount; + TileRegistry[TYPE_BELT].animation.divisor = 1; + } + + SDL_SetRenderTarget(renderer, oldTarget); +} + void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Rect playerRect, SDL_Renderer *renderer) { int px = x * TILE_SIZE; int py = y * TILE_SIZE; - Tile *t = &tileMap[y][x]; - - ItemType tileType = t->type; - - SDL_Rect src1, src2, dst1, dst2; - - if (dir == ORIENT_LEFT || dir == ORIENT_RIGHT) { - int offset = scrollFrame % TILE_SIZE; - - if (dir == ORIENT_RIGHT) { - offset = TILE_SIZE - offset; // reverse scroll - } - - src1 = (SDL_Rect) {offset, 0, TILE_SIZE - offset, TILE_SIZE}; - dst1 = (SDL_Rect) {px, py, (w - offset), h}; - - src2 = (SDL_Rect) {0, 0, offset, TILE_SIZE}; - dst2 = (SDL_Rect) {px + (w - offset), py, offset, h}; - - adjustRect(&dst1, playerRect); - adjustRect(&dst2, playerRect); - - SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src1, &dst1); //TODO CONVERT TO ATLAS - SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src2, &dst2); //TODO CONVERT TO ATLAS -// SDL_RenderCopyx(renderer, atlasTexture, &TileRegistry[tileType].atlasRects[dir], NULL); -// SDL_RenderCopyx(renderer, atlasTexture, &TileRegistry[tileType].atlasRects[dir], NULL); - } else { - int offset = scrollFrame % TILE_SIZE; - - if (dir == ORIENT_DOWN) { - offset = TILE_SIZE - offset; // reverse scroll - } - - src1 = (SDL_Rect) {0, offset, TILE_SIZE, TILE_SIZE - offset}; - dst1 = (SDL_Rect) {px, py, w, h - offset}; - - src2 = (SDL_Rect) {0, 0, TILE_SIZE, offset}; - dst2 = (SDL_Rect) {px, py + (h - offset), w, offset}; - - adjustRect(&dst1, playerRect); - adjustRect(&dst2, playerRect); - - - // Rotate to make the belt vertical -// SDL_RenderCopyx(renderer, atlasTexture, &ItemRegistry[item.type].atlasRectsOnBelt[ORIENT_LEFT], NULL); -// SDL_RenderCopyx(renderer, atlasTexture, &ItemRegistry[item.type].atlasRectsOnBelt[ORIENT_LEFT], NULL); - - SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src1, &dst1); - SDL_RenderCopy(renderer, TileRegistry[tileType].textures[dir], &src2, &dst2); - } -} - -void updateBelt(Tile * tile) { + SDL_Rect dst = {px, py, w, h}; + adjustRect(&dst, playerRect); + SDL_RenderCopy(renderer, atlasTexture, &TileRegistry[TYPE_BELT].animation.atlasRects[dir][ + (animationStep / TileRegistry[TYPE_BELT].animation.divisor) % + TileRegistry[TYPE_BELT].animation.frameCount], + &dst); } \ No newline at end of file diff --git a/tiles/belt.h b/tiles/belt.h index 6573d73..27f347b 100644 --- a/tiles/belt.h +++ b/tiles/belt.h @@ -11,8 +11,7 @@ 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); +void generateBeltFrames(SDL_Renderer *renderer); + void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Rect playerRect, SDL_Renderer *renderer); #endif //FACTORYGAME_BELT_H diff --git a/tiles/furnace.c b/tiles/furnace.c index e10ebac..8cf38ac 100644 --- a/tiles/furnace.c +++ b/tiles/furnace.c @@ -25,6 +25,13 @@ void updateFurnace(Tile *tile) { if (targetOutItemType != TYPE_AIR) { if (tile->miscVal == 0) { + if (outItem->type != TYPE_AIR) { + if (tile->audioCh < NUM_SYNTH_VOICES) { + audioData.synthVoices[tile->audioCh].volume = 0; + } + tile->fixedFrame = 1; + return; + } tile->audioCh = getAvailableChannel(); if (tile->audioCh < NUM_SYNTH_VOICES) { audioData.synthVoices[tile->audioCh].volume = 255; @@ -34,6 +41,7 @@ void updateFurnace(Tile *tile) { audioData.synthVoices[tile->audioCh].waveform = WAVE_SINE; audioData.synthVoices[tile->audioCh].frequency = 200; } + tile->fixedFrame = 0; } ++audioData.synthVoices[tile->audioCh].frequency; if (audioData.synthVoices[tile->audioCh].volume < 255) { @@ -43,10 +51,13 @@ void updateFurnace(Tile *tile) { if (tile->audioCh < NUM_SYNTH_VOICES) { audioData.synthVoices[tile->audioCh].volume = 0; } + tile->fixedFrame = 1; tile->miscVal = 0; inItem->type = 0; outItem->type = targetOutItemType; outItem->offset = -0.5f; } + } else { + tile->fixedFrame = 1; } } \ No newline at end of file diff --git a/tiles/miner.c b/tiles/miner.c index 61e54e5..61ec5f3 100644 --- a/tiles/miner.c +++ b/tiles/miner.c @@ -23,6 +23,7 @@ void updateMiner(Tile *tile) { if (targetOutItemType != TYPE_AIR && outItem->type == 0) { if (tile->miscVal == 0) { tile->audioCh = getAvailableChannel(); + tile->fixedFrame = 0; if (tile->audioCh < NUM_SYNTH_VOICES) { audioData.synthVoices[tile->audioCh].volume = 64; audioData.synthVoices[tile->audioCh].phase = 0; @@ -36,9 +37,12 @@ void updateMiner(Tile *tile) { if (tile->audioCh < NUM_SYNTH_VOICES) { audioData.synthVoices[tile->audioCh].volume = 0; } + tile->fixedFrame = 1; tile->miscVal = 0; outItem->type = targetOutItemType; outItem->offset = -0.5f; } + } else { + tile->fixedFrame = 1; } } \ No newline at end of file diff --git a/tiles/tile.c b/tiles/tile.c index c8ba568..e28e07c 100644 --- a/tiles/tile.c +++ b/tiles/tile.c @@ -2,6 +2,7 @@ // Created by bruno on 4/24/25. // +#include #include "tile.h" #include "../player/player.h" #include "furnace.h" @@ -73,57 +74,189 @@ void generateTestMap() { } -void registerTile(char name[20], SDL_Renderer *renderer) { - const char *dot = strchr(name, '.'); - memcpy(TileRegistry[tileTypeIndex].name, name, dot - name); +void registerTile(char fname[20], SDL_Renderer *renderer) { + + char name[21]; + + // Load animation frames + int frame = 0; + int indexTile = 0; char texturePath[80]; - snprintf(texturePath, 80, "./assets/tiles/%s", name); + + if (sscanf(fname, "%d_%20[^_]_%d.png", &indexTile, name, &frame) == 3) { + // Success: you now have index, fname, and frame + } else { + fprintf(stderr, "Invalid format: %s\n", fname); + } + strcpy(TileRegistry[indexTile].name, name); + snprintf(texturePath, sizeof(texturePath), "./assets/tiles/%s", fname); + SDL_Texture *texture = IMG_LoadTexture(renderer, texturePath); - TileRegistry[tileTypeIndex].textures[ORIENT_LEFT] = texture; - 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); - 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); + if (!texture) { + // Stop loading frames if the first one fails, or after all valid ones are added + if (frame == 0) { + fprintf(stderr, "Failed to load tile texture %s: %s\n", texturePath, IMG_GetError()); + } + } - 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); + for (int o = 0; o < ORIENT_DIRECTION_COUNT; o++) { + SDL_Texture *textures[ORIENT_DIRECTION_COUNT] = { + NULL, + texture, + NULL, + createFlippedTexture(renderer, texture, SDL_FLIP_HORIZONTAL), + NULL, + createRotatedTexture(renderer, texture, 90), + NULL, + createRotatedTexture(renderer, texture, 270) + }; - TileRegistry[tileTypeIndex].type = tileTypeIndex; - TileRegistry[tileTypeIndex].breakTime = 15; + printf("Bound %s to %d orient %s\n", fname, indexTile, OrientStrings[o]); + TileRegistry[indexTile].animation.textures[o][frame] = textures[o]; + SDL_SetTextureBlendMode(textures[o], SDL_BLENDMODE_BLEND); + TileRegistry[indexTile].animation.atlasRects[o][frame] = allocate_32x32(textures[o], renderer); + } - tileTypeIndex++; + TileRegistry[indexTile].type = indexTile; + TileRegistry[indexTile].animation.frameCount = frame + 1; + TileRegistry[indexTile].animation.divisor = 1; + + TileRegistry[indexTile].type = tileTypeIndex; + TileRegistry[indexTile].breakTime = 15; + + if (indexTile + 1 > tileTypeIndex) { + tileTypeIndex = indexTile + 1; + } } -void registerBackgroundTile(char name[20], SDL_Renderer *renderer) { - const char *dot = strchr(name, '.'); - memcpy(BackgroundTileRegistry[backgroundTileTypeIndex].name, name, dot - name); + +void registerBackgroundTile(char fname[20], SDL_Renderer *renderer) { + char name[21]; + + // Load animation frames + int frame = 0; + int indexBgTile = 0; char texturePath[80]; - snprintf(texturePath, 80, "./assets/backgrounds/%s", name); + + if (sscanf(fname, "%d_%20[^_]_%d.png", &indexBgTile, name, &frame) == 3) { + // Success: you now have index, fname, and frame + } else { + fprintf(stderr, "Invalid format: %s\n", fname); + } + strcpy(BackgroundTileRegistry[indexBgTile].name, name); + snprintf(texturePath, sizeof(texturePath), "./assets/backgrounds/%s", fname); 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); + if (!texture) { + if (frame == 0) { + fprintf(stderr, "Failed to load background texture %s: %s\n", texturePath, IMG_GetError()); + } + } - BackgroundTileRegistry[backgroundTileTypeIndex].type = backgroundTileTypeIndex; + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_NONE); - backgroundTileTypeIndex++; + printf("Bound %s to %d\n", fname, indexBgTile); + + BackgroundTileRegistry[indexBgTile].animation.textures[frame] = texture; + BackgroundTileRegistry[indexBgTile].animation.atlasRects[frame] = allocate_32x32(texture, renderer); + + BackgroundTileRegistry[indexBgTile].type = indexBgTile; + BackgroundTileRegistry[indexBgTile].animation.frameCount = frame + 1; + BackgroundTileRegistry[indexBgTile].animation.divisor = 1; + + if (indexBgTile + 1 > backgroundTileTypeIndex) { + backgroundTileTypeIndex = indexBgTile + 1; + } } +int compareStrings(const void *a, const void *b) { + const char *strA = *(const char **) a; + const char *strB = *(const char **) b; + return strcmp(strA, strB); +} void loadTiles(SDL_Renderer *renderer) { - iterateSortedDir("./assets/tiles", (DirEntryCallback) registerTile, renderer); - iterateSortedDir("./assets/backgrounds", (DirEntryCallback) registerBackgroundTile, renderer); + DIR *dir = opendir("./assets/tiles"); + if (!dir) { + perror("Failed to open tiles directory"); + return; + } + char *baseNames[MAX_BASE_NAMES]; + int baseNameCount = 0; + + struct dirent *entry; + while ((entry = readdir(dir))) { + char *dot = strrchr(entry->d_name, '.'); + if (!dot || strcmp(dot, ".png") != 0) continue; + + // Check if baseName already stored + int found = 0; + for (int i = 0; i < baseNameCount; ++i) { + if (strcmp(baseNames[i], entry->d_name) == 0) { + found = 1; + break; + } + } + + if (!found && baseNameCount < MAX_BASE_NAMES) { + baseNames[baseNameCount++] = strdup(entry->d_name); // Only store base, not full file name + } + } + closedir(dir); + + qsort(baseNames, baseNameCount, sizeof(char *), compareStrings); + + // Call registerTile on each base name + for (int i = 0; i < baseNameCount; ++i) { + char fileName[64]; + snprintf(fileName, sizeof(fileName), "%s", baseNames[i]); + registerTile(fileName, renderer); + free(baseNames[i]); + } + generateBeltFrames(renderer); + +} + + +void loadBackgroundTiles(SDL_Renderer *renderer) { + DIR *dir = opendir("./assets/backgrounds"); + if (!dir) { + perror("Failed to open backgrounds directory"); + return; + } + + char *baseNames[MAX_BASE_NAMES]; + int baseNameCount = 0; + + struct dirent *entry; + while ((entry = readdir(dir))) { + char *dot = strrchr(entry->d_name, '.'); + if (!dot || strcmp(dot, ".png") != 0) continue; + + // Check if baseName already stored + int found = 0; + for (int i = 0; i < baseNameCount; ++i) { + if (strcmp(baseNames[i], entry->d_name) == 0) { + found = 1; + break; + } + } + + if (!found && baseNameCount < MAX_BASE_NAMES) { + baseNames[baseNameCount++] = strdup(entry->d_name); // Only store base, not full file name + } + } + closedir(dir); + + qsort(baseNames, baseNameCount, sizeof(char *), compareStrings); + + // Call registerBackgroundTile on each base name + for (int i = 0; i < baseNameCount; ++i) { + char fileName[64]; + snprintf(fileName, sizeof(fileName), "%s", baseNames[i]); + registerBackgroundTile(fileName, renderer); + free(baseNames[i]); + } } void setupTiles() { @@ -144,10 +277,19 @@ void setupTiles() { } } TileRegistry[TYPE_FURNACE].outputLane[FURNACE_OUTPUT_SLOT] = 1; + TileRegistry[TYPE_FURNACE].startFrame = 1; TileRegistry[TYPE_FURNACE].needsTicks = true; + TileRegistry[TYPE_FURNACE].animation.divisor = 8; TileRegistry[TYPE_BELT].needsTicks = true; TileRegistry[TYPE_MINER].needsTicks = true; TileRegistry[TYPE_MINER].outputLane[MINER_OUTPUT_SLOT] = 1; + TileRegistry[TYPE_MINER].startFrame = 1; + + BackgroundTileRegistry[BGType_WATER_DEEP].animation.divisor = 16; + BackgroundTileRegistry[BGType_WATER_SHALLOW].animation.divisor = 12; + BackgroundTileRegistry[BGType_GRASS_FLOWER0].animation.divisor = 16; + BackgroundTileRegistry[BGType_GRASS_FLOWER1].animation.divisor = 16; + BackgroundTileRegistry[BGType_GRASS_FLOWER2].animation.divisor = 16; } uint16_t getBreakTime(int type) { @@ -205,8 +347,11 @@ void renderAllTiles(SDL_Renderer *renderer, SDL_Rect playerRect) { adjustRect(&dstRect, playerRect); BackgroundTile bt = backgroundMap[y][x]; - SDL_Texture *tex = BackgroundTileRegistry[bt.type].texture; - SDL_Rect atlRect = BackgroundTileRegistry[bt.type].atlasRect; + SDL_Texture *tex = BackgroundTileRegistry[bt.type].animation.textures[animationStep % + BackgroundTileRegistry[bt.type].animation.frameCount]; + SDL_Rect atlRect = BackgroundTileRegistry[bt.type].animation.atlasRects[ + (animationStep / BackgroundTileRegistry[bt.type].animation.divisor) % + BackgroundTileRegistry[bt.type].animation.frameCount]; if (atlRect.w != 0 && atlRect.h != 0) { SDL_RenderCopy(renderer, atlasTexture, &atlRect, &dstRect); //SDL_RenderCopy(renderer, tex, NULL, &dstRect); @@ -237,11 +382,18 @@ void renderAllTiles(SDL_Renderer *renderer, SDL_Rect playerRect) { renderBelt(x, y, tileSize, tileSize, t.direction, playerRect, renderer); break; default: { - SDL_Rect atlRect = TileRegistry[t.type].atlasRects[t.direction]; - SDL_Texture *tex = TileRegistry[t.type].textures[t.direction]; + char animationFrame = ((animationStep / TileRegistry[t.type].animation.divisor) % + (TileRegistry[t.type].animation.frameCount - + TileRegistry[t.type].startFrame)) + TileRegistry[t.type].startFrame; + if (t.fixedFrame > 0) { + animationFrame = t.fixedFrame - 1; + } + SDL_Rect atlRect = TileRegistry[t.type].animation.atlasRects[t.direction][animationFrame]; + SDL_Texture *tex = TileRegistry[t.type].animation.textures[t.direction][animationFrame]; if (atlRect.w == 0 || atlRect.h == 0) { - tex = TileRegistry[t.type].textures[ORIENT_LEFT]; - atlRect = TileRegistry[t.type].atlasRects[ORIENT_LEFT]; + tex = TileRegistry[t.type].animation.textures[ORIENT_LEFT][animationFrame]; + atlRect = TileRegistry[t.type].animation.atlasRects[ORIENT_LEFT][ + animationFrame]; } if (atlRect.w != 0 && atlRect.h != 0) { //SDL_RenderCopy(renderer, tex, NULL, &dstRect); diff --git a/tiles/tile.h b/tiles/tile.h index d9f7ce4..a3f4d65 100644 --- a/tiles/tile.h +++ b/tiles/tile.h @@ -49,20 +49,14 @@ extern unsigned long beltFrames; #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_WATER_SHALLOW, + BGType_WATER_DEEP, BGType_GRASS_FLOWER0, BGType_GRASS_FLOWER1, BGType_GRASS_FLOWER2, - BGType_GRASS_FLOWER3, + BGType_GRASS0, + BGType_GRASS1, + BGType_GRASS2, BGType_SAND0, BGType_SAND1, BGType_SAND2, @@ -86,23 +80,25 @@ typedef enum BackgroundType { BGType_END } BackgroundType; +#define MAX_BASE_NAMES 512 +#define MAX_ANIMATION_FRAMES 32 + typedef struct TileTypeReg { ItemType type; char name[20]; - SDL_Texture *textures[ORIENT_DIRECTION_COUNT]; - SDL_Rect atlasRects[ORIENT_DIRECTION_COUNT]; + OrientedAnimation animation; uint16_t breakTime; bool itemMoves; bool allowedInItems[ItemSlotCount][ITEMREGISTRY_SIZE]; bool outputLane[ItemSlotCount]; bool needsTicks; + char startFrame; } TileTypeReg; typedef struct BackgroundTileType { ItemType type; char name[20]; - SDL_Texture *texture; - SDL_Rect atlasRect; + Animation animation; } BackgroundTileType; typedef struct BackgroundTile { @@ -127,6 +123,7 @@ typedef struct Tile { uint16_t audioCh; MiniRect rect; int neededUpdateIndex; + char fixedFrame; } Tile; @@ -138,6 +135,8 @@ void setupTiles(); void generateTestMap(); +void loadBackgroundTiles(SDL_Renderer *renderer); + void loadTiles(SDL_Renderer *renderer); extern uint16_t tileTypeIndex; diff --git a/tiles/tilecallbacks.c b/tiles/tilecallbacks.c index ecd1ee2..64d6193 100644 --- a/tiles/tilecallbacks.c +++ b/tiles/tilecallbacks.c @@ -9,7 +9,7 @@ const UpdateTileCallback ItemTileCallbacks[TILEREGISTRY_SIZE] = { [TYPE_AIR] = NULL, [TYPE_BLOCK] = NULL, - [TYPE_BELT] = updateBelt, + [TYPE_BELT] = NULL, [TYPE_FURNACE] = updateFurnace, [TYPE_MINER] = updateMiner }; \ No newline at end of file diff --git a/util/atlas.c b/util/atlas.c index f839269..2d54609 100644 --- a/util/atlas.c +++ b/util/atlas.c @@ -10,7 +10,6 @@ SDL_Texture *atlasTexture; int tileIndex16 = 0, quadrantIndex16 = 0; int tileIndex32 = 0; -#define MAX_RECTS 256 int allocatedRectCount = 0; SDL_Rect allocatedRects[MAX_RECTS]; diff --git a/util/atlas.h b/util/atlas.h index 85b4a3f..5d79913 100644 --- a/util/atlas.h +++ b/util/atlas.h @@ -5,7 +5,8 @@ #ifndef FACTORYGAME_ATLAS_H #define FACTORYGAME_ATLAS_H -#define ATLAS_SIZE 512 +#define ATLAS_SIZE 1024 +#define MAX_RECTS 2048 #define TILE_SIZE 32 #define QUADRANT_SIZE 16 #define ATLAS_TILES_PER_ROW (ATLAS_SIZE / TILE_SIZE) diff --git a/util/util.c b/util/util.c index a08f080..f6c3ba7 100644 --- a/util/util.c +++ b/util/util.c @@ -11,6 +11,19 @@ SDL_Window *window = NULL; volatile bool running = true; +const char OrientStrings[ORIENT_DIRECTION_COUNT][10] = { + "LEFT_DOWN", + "LEFT", + "LEFT_UP", + "UP", + "RIGHT_UP", + "RIGHT", + "RIGHT_DOWN", + "DOWN", +}; + +int animationStep = 0; + bool debugMode = false; bool itemViewing = false; bool renderAtlas = false; diff --git a/util/util.h b/util/util.h index b30f61f..87bdcae 100644 --- a/util/util.h +++ b/util/util.h @@ -6,6 +6,9 @@ #define FACTORYGAME_UTIL_H #include +#include "atlas.h" + +extern int animationStep; //The window we'll be rendering to extern SDL_Window *window; @@ -16,7 +19,7 @@ extern SDL_Renderer *mainRenderer; extern SDL_Rect screenRect; -typedef enum OrientDirection{ +typedef enum OrientDirection { ORIENT_LEFT_DOWN, ORIENT_LEFT, ORIENT_LEFT_UP, @@ -28,10 +31,28 @@ typedef enum OrientDirection{ ORIENT_DIRECTION_COUNT } OrientDirection; +extern const char OrientStrings[ORIENT_DIRECTION_COUNT][10]; + extern bool debugMode; extern bool itemViewing; extern bool renderAtlas; +typedef struct Animation { + SDL_Texture *textures[TILE_SIZE]; + SDL_Rect atlasRects[TILE_SIZE]; + unsigned char frameCount; + unsigned char divisor; +} Animation; + + +typedef struct OrientedAnimation { + SDL_Texture *textures[ORIENT_DIRECTION_COUNT][TILE_SIZE * 2]; + SDL_Rect atlasRects[ORIENT_DIRECTION_COUNT][TILE_SIZE * 2]; + unsigned char frameCount; + unsigned char divisor; +} OrientedAnimation; + + SDL_Texture *createRotatedTexture(SDL_Renderer *renderer, SDL_Texture *src, double angle); SDL_Texture *createFlippedTexture(SDL_Renderer *renderer, SDL_Texture *src, SDL_RendererFlip flip);