fix: minimap sempre tirava a gastar standard.gif

This commit is contained in:
2026-04-11 07:55:26 +02:00
parent fadc3b03c9
commit 0d4b7f518c
6 changed files with 98 additions and 84 deletions

View File

@@ -21,7 +21,6 @@
MiniMap::MiniMap(Uint8 bg_color, Uint8 conn_color)
: bg_color_(bg_color),
conn_color_(conn_color) {
buildTileColorTable("standard.gif");
layoutRooms();
buildRoomSurfaces();
composeFinalSurface();
@@ -34,47 +33,54 @@ void MiniMap::rebuild(Uint8 bg_color, Uint8 conn_color) {
composeFinalSurface();
}
// Analiza el tileset y crea tabla: tile_index → color predominante
void MiniMap::buildTileColorTable(const std::string& tileset_name) {
// Devuelve (construyendo si hace falta) la tabla de color predominante para un tileset
auto MiniMap::getOrBuildTileColorTable(const std::string& tileset_name) -> const TileColorTable& {
auto it = tileset_tables_.find(tileset_name);
if (it != tileset_tables_.end()) { return it->second; }
// Inserta entrada vacía. Si el tileset no se puede cargar, esto evita reintentos.
auto& table = tileset_tables_[tileset_name];
auto tileset = Resource::Cache::get()->getSurface(tileset_name);
if (!tileset) { return; }
if (!tileset) { return table; }
tileset_width_ = static_cast<int>(tileset->getWidth()) / Tile::SIZE;
tileset_transparent_ = tileset->getTransparentColor();
table.tileset_width = static_cast<int>(tileset->getWidth()) / Tile::SIZE;
table.transparent = tileset->getTransparentColor();
int tileset_height = static_cast<int>(tileset->getHeight()) / Tile::SIZE;
int total_tiles = tileset_width_ * tileset_height;
int total_tiles = table.tileset_width * tileset_height;
tile_colors_.resize(total_tiles, 0);
table.colors.resize(total_tiles, 0);
for (int tile = 0; tile < total_tiles; ++tile) {
int tile_x = (tile % tileset_width_) * Tile::SIZE;
int tile_y = (tile / tileset_width_) * Tile::SIZE;
int tile_x = (tile % table.tileset_width) * Tile::SIZE;
int tile_y = (tile / table.tileset_width) * Tile::SIZE;
// Contar frecuencia de cada color en el tile (ignorar el color transparente del tileset)
Uint8 transparent = tileset->getTransparentColor();
std::array<int, 256> freq{};
for (int y = 0; y < Tile::SIZE; ++y) {
for (int x = 0; x < Tile::SIZE; ++x) {
Uint8 pixel = tileset->getPixel(tile_x + x, tile_y + y);
if (pixel != transparent) {
if (pixel != table.transparent) {
freq[pixel]++;
}
}
}
// Encontrar el color más frecuente (transparent = tile vacío, no se pinta)
Uint8 best_color = transparent;
Uint8 best_color = table.transparent;
int best_count = 0;
for (int c = 0; c < 256; ++c) {
if (c == transparent) { continue; }
if (c == table.transparent) { continue; }
if (freq[c] > best_count) {
best_count = freq[c];
best_color = static_cast<Uint8>(c);
}
}
tile_colors_[tile] = best_color;
table.colors[tile] = best_color;
}
return table;
}
// Posiciona las rooms en un grid usando BFS desde las conexiones
@@ -178,6 +184,9 @@ auto MiniMap::getRoomMiniSurface(const std::string& room_name) -> std::shared_pt
}
if (!room_data) { return nullptr; }
// Tabla de colores específica del tileset que usa esta room (cacheada).
const auto& table = getOrBuildTileColorTable(room_data->tile_set_file);
auto surface = std::make_shared<Surface>(ROOM_W, ROOM_H);
auto prev = Screen::get()->getRendererSurface();
@@ -191,10 +200,10 @@ auto MiniMap::getRoomMiniSurface(const std::string& room_name) -> std::shared_pt
if (index >= static_cast<int>(tile_map.size())) { continue; }
int tile = tile_map[index];
if (tile < 0 || tile >= static_cast<int>(tile_colors_.size())) { continue; }
if (tile < 0 || tile >= static_cast<int>(table.colors.size())) { continue; }
Uint8 color = tile_colors_[tile];
if (color != tileset_transparent_) {
Uint8 color = table.colors[tile];
if (color != table.transparent) {
surface->putPixel(x, y, color);
}
}

View File

@@ -49,7 +49,14 @@ class MiniMap {
GridPos pos; // Posición en el grid
};
void buildTileColorTable(const std::string& tileset_name);
// Tabla de color predominante para un tileset concreto
struct TileColorTable {
std::vector<Uint8> colors; // tile_index → palette color
int tileset_width{0}; // Ancho del tileset en tiles
Uint8 transparent{16}; // Color transparente del tileset
};
auto getOrBuildTileColorTable(const std::string& tileset_name) -> const TileColorTable&;
void buildRoomSurfaces();
void layoutRooms();
void composeFinalSurface();
@@ -59,10 +66,8 @@ class MiniMap {
auto cellPixelX(int grid_x) const -> int { return PADDING + ((grid_x - min_grid_x_) * (CELL_W + GAP)); }
auto cellPixelY(int grid_y) const -> int { return PADDING + ((grid_y - min_grid_y_) * (CELL_H + GAP)); }
// Tabla de color predominante por tile index
std::vector<Uint8> tile_colors_; // tile_index → palette color index
int tileset_width_{0}; // Ancho del tileset en tiles
Uint8 tileset_transparent_{16}; // Color transparente del tileset
// Caché de tablas de color por tileset (clave: nombre del fichero del tileset)
std::unordered_map<std::string, TileColorTable> tileset_tables_;
// Rooms renderizadas y posicionadas
std::unordered_map<std::string, RoomMini> room_positions_;