#include "tileset.h" #include #include #include int tileset_init(Tileset *ts, int tile_w, int tile_h) { if (ts == NULL) return 0; if (tile_w <= 0 || tile_h <= 0) return 0; memset(ts, 0, sizeof(Tileset)); ts->tile_w = tile_w; ts->tile_h = tile_h; // Compute grid dimensions to fit MAX_TILE_ID tiles ts->atlas_cols = 4; // 4 columns ts->atlas_rows = (MAX_TILE_ID + ts->atlas_cols - 1) / ts->atlas_cols; // round up int atlas_w = ts->atlas_cols * tile_w; int atlas_h = ts->atlas_rows * tile_h; // Validate atlas dimensions are reasonable if (atlas_w <= 0 || atlas_h <= 0 || atlas_w > 4096 || atlas_h > 4096) return 0; ts->render_target = LoadRenderTexture(atlas_w, atlas_h); if (!IsRenderTextureValid(ts->render_target)) return 0; // Clear to transparent so unpainted regions don't show artifacts BeginTextureMode(ts->render_target); ClearBackground(BLANK); EndTextureMode(); ts->finalized = 0; ts->tile_count = 0; return 1; } int tileset_register(Tileset *ts, int id) { if (ts == NULL) return 0; if (id < 0 || id >= MAX_TILE_ID) return 0; if (ts->render_target.id == 0) return 0; if (ts->finalized) return 0; if (ts->regions[id].width != 0) return 0; // already registered int col = id % ts->atlas_cols; int row = id / ts->atlas_cols; ts->regions[id] = (Rectangle){(float)(col * ts->tile_w), (float)(row * ts->tile_h), (float)ts->tile_w, (float)ts->tile_h}; ts->tile_count++; return 1; } int tileset_finalize(Tileset *ts) { if (ts == NULL) return 0; if (ts->render_target.id == 0) return 0; if (ts->finalized) return 1; // already finalized // Convert RenderTexture to regular Texture2D // RenderTexture textures are flipped vertically in raylib, so we need to handle that Texture2D old_texture = ts->render_target.texture; // Create a new texture from the render texture data Image img = LoadImageFromTexture(old_texture); if (img.data == NULL) { return 0; } // Flip image vertically because RenderTexture is upside-down ImageFlipVertical(&img); Texture2D new_tex = LoadTextureFromImage(img); UnloadImage(img); if (new_tex.id == 0) { return 0; } // Unload the old render texture and replace with the new regular texture UnloadRenderTexture(ts->render_target); ts->render_target.id = 0; ts->atlas = new_tex; ts->finalized = 1; return 1; } Rectangle tileset_get_region(const Tileset *ts, int id) { if (ts == NULL || id < 0 || id >= MAX_TILE_ID) return (Rectangle){0, 0, 0, 0}; if (!ts->finalized) return (Rectangle){0, 0, 0, 0}; return ts->regions[id]; } void tileset_destroy(Tileset *ts) { if (ts == NULL) return; if (ts->finalized) { if (ts->atlas.id != 0) UnloadTexture(ts->atlas); } else { if (ts->render_target.id != 0) UnloadRenderTexture(ts->render_target); } memset(ts, 0, sizeof(Tileset)); }