diff options
Diffstat (limited to 'crawl-ref/source/rltiles/tool')
-rw-r--r-- | crawl-ref/source/rltiles/tool/tile.cc | 43 | ||||
-rw-r--r-- | crawl-ref/source/rltiles/tool/tile.h | 20 | ||||
-rw-r--r-- | crawl-ref/source/rltiles/tool/tile_colour.cc | 220 | ||||
-rw-r--r-- | crawl-ref/source/rltiles/tool/tile_colour.h | 49 | ||||
-rw-r--r-- | crawl-ref/source/rltiles/tool/tile_list_processor.cc | 390 | ||||
-rw-r--r-- | crawl-ref/source/rltiles/tool/tile_list_processor.h | 17 | ||||
-rw-r--r-- | crawl-ref/source/rltiles/tool/tile_page.cc | 34 | ||||
-rw-r--r-- | crawl-ref/source/rltiles/tool/tile_page.h | 5 |
8 files changed, 703 insertions, 75 deletions
diff --git a/crawl-ref/source/rltiles/tool/tile.cc b/crawl-ref/source/rltiles/tool/tile.cc index 2febfd73b2..65d82c9b18 100644 --- a/crawl-ref/source/rltiles/tool/tile.cc +++ b/crawl-ref/source/rltiles/tool/tile.cc @@ -17,9 +17,12 @@ tile::tile(const tile &img, const char *enumnam, const char *parts) : copy(img); if (enumnam) - m_enumname = enumnam; + m_enumname.push_back(enumnam); if (parts) m_parts_ctg = parts; + + for (int i = 0; i < MAX_COLOUR; ++i) + m_variations[i] = -1; } tile::~tile() @@ -39,27 +42,37 @@ bool tile::valid() const return m_pixels && m_width && m_height; } -const std::string &tile::filename() +const std::string &tile::filename() const { return m_filename; } -const std::string &tile::enumname() +int tile::enumcount() const +{ + return m_enumname.size(); +} + +const std::string &tile::enumname(int idx) const { - return m_enumname; + return m_enumname[idx]; } -const std::string &tile::parts_ctg() +void tile::add_enumname(const std::string &name) +{ + m_enumname.push_back(name); +} + +const std::string &tile::parts_ctg() const { return m_parts_ctg; } -int tile::width() +int tile::width() const { return m_width; } -int tile::height() +int tile::height() const { return m_height; } @@ -484,3 +497,19 @@ void tile::get_bounding_box(int &x0, int &y0, int &w, int &h) w = x1 - x0 + 1; h = y1 - y0 + 1; } + +void tile::add_variation(int colour, int idx) +{ + assert(colour >= 0); + assert(colour < MAX_COLOUR); + m_variations[colour] = idx; +} + +bool tile::get_variation(int colour, int &idx) +{ + if (m_variations[colour] == -1) + return (false); + + idx = m_variations[colour]; + return (true); +} diff --git a/crawl-ref/source/rltiles/tool/tile.h b/crawl-ref/source/rltiles/tool/tile.h index b14e14d100..7381763ead 100644 --- a/crawl-ref/source/rltiles/tool/tile.h +++ b/crawl-ref/source/rltiles/tool/tile.h @@ -3,6 +3,7 @@ #include "tile_colour.h" #include <string> +#include <vector> class tile { @@ -30,25 +31,32 @@ public: void replace_colour(tile_colour &find, tile_colour &replace); void fill(const tile_colour &col); - const std::string &filename(); - const std::string &enumname(); - const std::string &parts_ctg(); - int width(); - int height(); + const std::string &filename() const; + int enumcount() const; + const std::string &enumname(int idx) const; + void add_enumname(const std::string &name); + const std::string &parts_ctg() const; + int width() const; + int height() const; bool shrink(); void set_shrink(bool new_shrink); void get_bounding_box(int &x0, int &y0, int &w, int &h); tile_colour &get_pixel(unsigned int x, unsigned int y); + + void add_variation(int colour, int idx); + bool get_variation(int colour, int &idx); protected: int m_width; int m_height; std::string m_filename; - std::string m_enumname; + std::vector<std::string> m_enumname; std::string m_parts_ctg; tile_colour *m_pixels; bool m_shrink; + + int m_variations[MAX_COLOUR]; }; #endif diff --git a/crawl-ref/source/rltiles/tool/tile_colour.cc b/crawl-ref/source/rltiles/tool/tile_colour.cc index f1969f37be..2f098b387b 100644 --- a/crawl-ref/source/rltiles/tool/tile_colour.cc +++ b/crawl-ref/source/rltiles/tool/tile_colour.cc @@ -28,6 +28,226 @@ const tile_colour &tile_colour::operator=(const tile_colour &rhs) return (*this); } +unsigned char &tile_colour::operator[](int idx) +{ + assert(idx >= 0 && idx <= 4); + switch (idx) + { + default: + case 0: return r; + case 1: return g; + case 2: return b; + case 3: return a; + } +} + +unsigned char tile_colour::operator[](int idx) const +{ + assert(idx >= 0 && idx <= 4); + switch (idx) + { + default: + case 0: return r; + case 1: return g; + case 2: return b; + case 3: return a; + } +} + +int tile_colour::get_hue() const +{ + int max_rgb = get_max_rgb(); + int min_rgb = get_min_rgb(); + + if (max_rgb == min_rgb) + return (0); + + int diff = max_rgb - min_rgb; + + if (max_rgb == r) + { + return ((60 * (g - b)) / diff + 360) % 360; + } + else if (max_rgb == g) + { + return (60 * (b - r)) / diff + 120; + } + else // if (max_rgb == b) + { + return (60 * (r - g)) / diff + 240; + } +} + +int tile_colour::get_max_rgb() const +{ + int max_rgb = std::max(std::max(r, g), b); + return (max_rgb); +} + +int tile_colour::get_min_rgb() const +{ + int min_rgb = std::min(std::min(r, g), b); + return (min_rgb); +} + +void tile_colour::set_hue(int h) +{ + set_from_hue(h, get_min_rgb(), get_max_rgb()); +} + +void tile_colour::set_from_hue(int h, int min_rgb, int max_rgb) +{ + // http://en.wikipedia.org/wiki/HSL_and_HSV + // H is passed in + // S = diff / max or 0 if max == 0 + // V = max / 255 + + int v = max_rgb; + int s = max_rgb - min_rgb; + + float f = ((float)h / 60.0f) - (int)(h / 60); + + // When calculating P, Q, T, also convert to 0..255 range. + int p = v - s; + int q = v - f * s; + int t = v - (1.0f - f) * s; + + // Sanity bounds. + q = std::max(std::min(q, 255), 0); + t = std::max(std::min(t, 255), 0); + + int h_idx = (h / 60) % 6; + + switch (h_idx) + { + default: + case 0: + r = static_cast<unsigned char>(v); + g = static_cast<unsigned char>(t); + b = static_cast<unsigned char>(p); + break; + case 1: + r = static_cast<unsigned char>(q); + g = static_cast<unsigned char>(v); + b = static_cast<unsigned char>(p); + break; + case 2: + r = static_cast<unsigned char>(p); + g = static_cast<unsigned char>(v); + b = static_cast<unsigned char>(t); + break; + case 3: + r = static_cast<unsigned char>(p); + g = static_cast<unsigned char>(q); + b = static_cast<unsigned char>(v); + break; + case 4: + r = static_cast<unsigned char>(t); + g = static_cast<unsigned char>(p); + b = static_cast<unsigned char>(v); + break; + case 5: + r = static_cast<unsigned char>(v); + g = static_cast<unsigned char>(p); + b = static_cast<unsigned char>(q); + break; + } +} + +void tile_colour::desaturate() +{ + set_from_hue(get_hue(), get_max_rgb(), get_max_rgb()); +} + +float tile_colour::get_lum() const +{ + return ((get_min_rgb() + get_max_rgb()) / (255 * 2.0f)); +} + +float tile_colour::get_sat() const +{ + int min_rgb = get_min_rgb(); + int max_rgb = get_max_rgb(); + int sum = min_rgb + max_rgb; + + float sat; + if (sum == 0) + sat = 0; + else if (sum > 255) + sat = (max_rgb - min_rgb) / (float)(255*2 - min_rgb - max_rgb); + else + sat = (max_rgb - min_rgb) / (float)(min_rgb + max_rgb); + + return (sat); +} + +void tile_colour::set_from_hsl(int hue, float sat, float lum) +{ + float q; + if (lum < 0.5f) + q = lum * (1 + sat); + else + q = lum + sat - (lum * sat); + + float p = 2 * lum - q; + + for (int i = 0; i < 3; ++i) + { + int h = hue + (1 - i) * 120; + if (h < 0) + h += 360; + if (h >= 360) + h -= 360; + + float val; + + if (h < 60) + val = p + (q - p) * h / 60.0f; + else if (h < 180) + val = q; + else if (h < 240) + val = p + (q - p) * (4 - h / 60.0f); + else + val = p; + + int final = val * 255; + final = std::max(0, std::min(255, final)); + (*this)[i] = static_cast<unsigned char>(final); + } +} + +void tile_colour::change_lum(int lum_percent) +{ + int min_rgb = get_min_rgb(); + int max_rgb = get_max_rgb(); + int hue = get_hue(); + + if (min_rgb == max_rgb) + { + int rgb_change = (lum_percent * 255) / 100; + + min_rgb += rgb_change; + max_rgb += rgb_change; + + min_rgb = std::max(0, std::min(255, min_rgb)); + max_rgb = std::max(0, std::min(255, max_rgb)); + + set_from_hue(get_hue(), min_rgb, max_rgb); + return; + } + + float lum_change = lum_percent / 100.0f; + float lum = get_lum() + lum_change; + + if (lum > 1.0f) + lum = 1.0f; + if (lum < 0.0f) + lum = 0.0f; + + float sat = get_sat(); + set_from_hsl(hue, sat, lum); +} + bool write_png(const char *filename, tile_colour *pixels, unsigned int width, unsigned int height) { diff --git a/crawl-ref/source/rltiles/tool/tile_colour.h b/crawl-ref/source/rltiles/tool/tile_colour.h index 4c77162b9f..f660c84829 100644 --- a/crawl-ref/source/rltiles/tool/tile_colour.h +++ b/crawl-ref/source/rltiles/tool/tile_colour.h @@ -1,6 +1,30 @@ #ifndef TILE_COLOUR_H #define TILE_COLOUR_H +enum COLORS +{ + BLACK, + BLUE, + GREEN, + CYAN, + RED, + MAGENTA, + BROWN, + LIGHTGRAY, + LIGHTGREY = LIGHTGRAY, + DARKGRAY, + DARKGREY = DARKGRAY, + LIGHTBLUE, + LIGHTGREEN, + LIGHTCYAN, + LIGHTRED, + LIGHTMAGENTA, + YELLOW, + WHITE, + MAX_TERM_COLOUR, + MAX_COLOUR = MAX_TERM_COLOUR +}; + class tile_colour { public: @@ -12,6 +36,31 @@ public: bool operator!=(const tile_colour &rhs) const; const tile_colour &operator=(const tile_colour &rhs); + unsigned char &operator[](int idx); + unsigned char operator[](int idx) const; + + // Get the HSV/HSL hue, from 0..360. + int get_hue() const; + // Set the hue, from 0..360. + void set_hue(int h); + // Change the saturation to 0. + void desaturate(); + // Change the luminance by lum_percent %. + void change_lum(int lum_percent); + + int get_max_rgb() const; + int get_min_rgb() const; + + // Set the color from HSV. hue is 0..360. min_rgb and max_rgb are 0..255. + void set_from_hue(int hue, int min_rgb, int max_rgb); + + // Set the color from HSL. hue is 0..360. sat and lum are 0..1. + void set_from_hsl(int hue, float sat, float lum); + // Get the HSL saturation, from 0..1. + float get_sat() const; + // Get the HSL luminance, from 0..1. + float get_lum() const; + unsigned char r; unsigned char g; unsigned char b; diff --git a/crawl-ref/source/rltiles/tool/tile_list_processor.cc b/crawl-ref/source/rltiles/tool/tile_list_processor.cc index 091d195fca..dfd8385296 100644 --- a/crawl-ref/source/rltiles/tool/tile_list_processor.cc +++ b/crawl-ref/source/rltiles/tool/tile_list_processor.cc @@ -17,7 +17,9 @@ tile_list_processor::tile_list_processor() : m_composing(false), m_shrink(true), m_prefix("TILE"), - m_start_value("0") + m_start_value("0"), + m_variation_idx(-1), + m_variation_col(-1) { } @@ -150,6 +152,73 @@ static void eat_comments(char *&text) } } +static const std::string colour_list[16] = +{ + "black", "blue", "green", "cyan", "red", "magenta", "brown", + "lightgrey", "darkgrey", "lightblue", "lightgreen", "lightcyan", + "lightred", "lightmagenta", "yellow", "white" +}; + +static int str_to_colour(std::string colour) +{ + if (colour.empty()) + return (0); + + for (unsigned int c = 0; c < colour.size(); c++) + colour[c] = std::tolower(colour[c]); + + for (int i = 0; i < 16; ++i) + { + if (colour == colour_list[i]) + return (i); + } + + // Check for alternate spellings. + if (colour == "lightgray") + return (7); + else if (colour == "darkgray") + return (8); + + return (0); +} + +void tile_list_processor::recolour(tile &img) +{ + for (int y = 0; y < img.height(); ++y) + for (int x = 0; x < img.width(); ++x) + { + tile_colour &col = img.get_pixel(x, y); + tile_colour orig = col; + for (palette_list::iterator iter = m_palette.begin(); + iter != m_palette.end(); ++iter) + { + if (orig == iter->first) + col = iter->second; + } + + for (hue_list::iterator iter = m_hues.begin(); + iter != m_hues.end(); ++iter) + { + if (orig.get_hue() == iter->first) + col.set_hue(iter->second); + } + + for (desat_list::iterator iter = m_desat.begin(); + iter != m_desat.end(); ++iter) + { + if (orig.get_hue() == *iter) + col.desaturate(); + } + + for (lum_list::iterator iter = m_lum.begin(); + iter != m_lum.end(); ++iter) + { + if (orig.get_hue() == iter->first) + col.change_lum(iter->second); + } + } +} + bool tile_list_processor::process_line(char *read_line, const char *list_file, int line) { @@ -254,6 +323,8 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, if (m_rim) img.add_rim(tile_colour::black); + recolour(img); + if (!m_compose.compose(img)) { fprintf(stderr, "Error (%s:%d): failed composing '%s'" @@ -270,6 +341,8 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, "'%s'.\n", list_file, line, m_args[1]); return (false); } + + recolour(m_compose); } } else if (strcmp(arg, "corpse") == 0) @@ -409,6 +482,133 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, if (m_args.size() > 2) m_include = m_args[2]; } + else if (strcmp(arg, "pal") == 0) + { + // rgb (optional a) = rgb (optional a) + tile_colour cols[2] = { tile_colour::black, tile_colour::black }; + int col_idx = 0; + int comp_idx = 0; + + for (size_t i = 1; i < m_args.size(); ++i) + { + if (strcmp(m_args[i], "=")) + { + if (comp_idx > 3) + { + fprintf(stderr, "Error (%s:%d): " + "Must be R G B (A) = R G B (A).\n", + list_file, line); + return (false); + } + + int val = atoi(m_args[i]); + if (val < 0 || val > 255) + { + fprintf(stderr, + "Error (%s:%d): Arg %d must be 0-255.\n", + list_file, line, i); + } + + cols[col_idx][comp_idx++] = static_cast<unsigned char>(val); + } + else if (col_idx > 0) + { + fprintf(stderr, + "Error (%s:%d): Too many '=' characters.\n", + list_file, line); + return (false); + } + else + { + col_idx++; + comp_idx = 0; + } + } + + m_palette.push_back(palette_entry(cols[0], cols[1])); + } + else if (strcmp(arg, "hue") == 0) + { + CHECK_ARG(2); + m_hues.push_back(int_pair(atoi(m_args[1]), atoi(m_args[2]))); + } + else if (strcmp(arg, "resetcol") == 0) + { + CHECK_NO_ARG(1); + m_palette.clear(); + m_hues.clear(); + m_desat.clear(); + m_lum.clear(); + } + else if (strcmp(arg, "desat") == 0) + { + CHECK_ARG(1); + CHECK_NO_ARG(2); + + m_desat.push_back(atoi(m_args[1])); + } + else if (strcmp(arg, "lum") == 0) + { + CHECK_ARG(2); + CHECK_NO_ARG(3); + + m_lum.push_back(int_pair(atoi(m_args[1]), atoi(m_args[2]))); + } + else if (strcmp(arg, "variation") == 0) + { + CHECK_ARG(2); + CHECK_NO_ARG(3); + + int idx = m_page.find(m_args[1]); + if (idx == -1) + { + fprintf(stderr, "Error (%s:%d): invalid tile name '%s'\n", + list_file, line, m_args[1]); + return (false); + } + + int colour = str_to_colour(m_args[2]); + if (colour == 0) + { + fprintf(stderr, "Error (%s:%d): invalid colour '%s'\n", + list_file, line, m_args[2]); + return (false); + } + + m_variation_idx = idx; + m_variation_col = colour; + } + else if (strcmp(arg, "repeat") == 0) + { + CHECK_ARG(1); + + int idx = m_page.find(m_args[1]); + if (idx == -1) + { + fprintf(stderr, "Error (%s:%d): invalid tile name '%s'\n", + list_file, line, m_args[1]); + return (false); + } + + int cnt = m_page.m_counts[idx]; + + for (int i = 0; i < cnt; ++i) + { + tile img; + img.copy(*m_page.m_tiles[idx + i]); + recolour(img); + add_image(img, (i == 0 && m_args[2]) ? m_args[2] : NULL); + } + + if (m_args.size() > 2) + { + for (int i = 3; i < m_args.size(); ++i) + { + // Add enums for additional values. + m_page.add_synonym(m_args[2], m_args[i]); + } + } + } else { fprintf(stderr, "Error (%s:%d): unknown command '%%%s'\n", @@ -464,11 +664,19 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, img.corpsify(); } + recolour(img); + if (m_rim && !m_corpsify) img.add_rim(tile_colour::black); // Push tile onto tile page. add_image(img, m_args.size() > 1 ? m_args[1] : NULL); + + for (int i = 2; i < m_args.size(); ++i) + { + // Add enums for additional values. + m_page.add_synonym(m_args[1], m_args[i]); + } } return (true); @@ -489,6 +697,12 @@ void tile_list_processor::add_image(tile &img, const char *enumname) if (m_categories.size() > 0) m_ctg_counts[m_categories.size()-1]++; + + if (m_variation_idx != -1) + { + m_page.add_variation(m_last_enum, m_variation_idx, m_variation_col); + m_variation_idx = -1; + } } bool tile_list_processor::write_data() @@ -560,24 +774,47 @@ bool tile_list_processor::write_data() for (unsigned int i = 0; i < m_page.m_tiles.size(); i++) { - const std::string &enumname = m_page.m_tiles[i]->enumname(); const std::string &parts_ctg = m_page.m_tiles[i]->parts_ctg(); - if (enumname.empty()) + int enumcount = m_page.m_tiles[i]->enumcount(); + + std::string full_enum; + if (enumcount == 0) { fprintf(fp, " %s_%s_FILLER_%d%s,\n", m_prefix.c_str(), ucname.c_str(), i, start_val.c_str()); } else if (parts_ctg.empty()) { + const std::string &enumname = m_page.m_tiles[i]->enumname(0); fprintf(fp, " %s_%s%s,\n", m_prefix.c_str(), enumname.c_str(), start_val.c_str()); } else { + const std::string &enumname = m_page.m_tiles[i]->enumname(0); fprintf(fp, " %s_%s_%s%s,\n", m_prefix.c_str(), parts_ctg.c_str(), enumname.c_str(), start_val.c_str()); } + for (int c = 1; c < enumcount; ++c) + { + const std::string &basename = m_page.m_tiles[i]->enumname(0); + const std::string &enumname = m_page.m_tiles[i]->enumname(c); + + if (parts_ctg.empty()) + { + fprintf(fp, " %s_%s = %s_%s,\n", + m_prefix.c_str(), enumname.c_str(), + m_prefix.c_str(), basename.c_str()); + } + else + { + fprintf(fp, " %s_%s_%s = %s_%s_%s,\n", + m_prefix.c_str(), parts_ctg.c_str(), enumname.c_str(), + m_prefix.c_str(), parts_ctg.c_str(), basename.c_str()); + } + } + start_val = ""; if (!parts_ctg.empty()) @@ -597,13 +834,15 @@ bool tile_list_processor::write_data() fprintf(fp, "int tile_%s_count(unsigned int idx);\n", lcname.c_str()); fprintf(fp, "const char *tile_%s_name(unsigned int idx);\n", - lcname.c_str()); + lcname.c_str()); fprintf(fp, "tile_info &tile_%s_info(unsigned int idx);\n", - lcname.c_str()); + lcname.c_str()); fprintf(fp, "bool tile_%s_index(const char *str, unsigned int &idx);\n", - lcname.c_str()); + lcname.c_str()); fprintf(fp, "bool tile_%s_equal(unsigned int tile, unsigned int idx);\n", - lcname.c_str()); + lcname.c_str()); + fprintf(fp, "unsigned int tile_%s_coloured(unsigned int idx, int col);\n", + lcname.c_str()); if (m_categories.size() > 0) { @@ -663,11 +902,15 @@ bool tile_list_processor::write_data() lcname.c_str(), max.c_str(), m_start_value.c_str()); for (unsigned int i = 0; i < m_page.m_tiles.size(); i++) { - const std::string &enumname = m_page.m_tiles[i]->enumname(); - if (enumname.empty()) + if (m_page.m_tiles[i]->enumcount() == 0) + { fprintf(fp, " \"%s_FILLER_%d\",\n", ucname.c_str(), i); + } else + { + const std::string &enumname = m_page.m_tiles[i]->enumname(0); fprintf(fp, " \"%s\",\n", enumname.c_str()); + } } fprintf(fp, "};\n\n"); @@ -718,9 +961,9 @@ bool tile_list_processor::write_data() fprintf(fp, "};\n\n"); } - fprintf(fp, "\ntypedef std::pair<const char*, int> _tile_pair;\n\n"); + fprintf(fp, "\ntypedef std::pair<const char*, unsigned int> _name_pair;\n\n"); - fprintf(fp, "_tile_pair %s_map_pairs[] =\n" + fprintf(fp, "_name_pair %s_name_pairs[] =\n" "{\n", lcname.c_str()); typedef std::map<std::string, int> sort_map; @@ -728,22 +971,22 @@ bool tile_list_processor::write_data() for (unsigned int i = 0; i < m_page.m_tiles.size(); i++) { - const std::string &enumname = m_page.m_tiles[i]->enumname(); - // Filler can't be looked up. - if (enumname.empty()) - continue; + for (int c = 0; c < m_page.m_tiles[i]->enumcount(); ++c) + { + const std::string &enumname = m_page.m_tiles[i]->enumname(c); - std::string lcenum = enumname; - for (unsigned int c = 0; c < enumname.size(); c++) - lcenum[c] = std::tolower(enumname[c]); + std::string lcenum = enumname; + for (unsigned int c = 0; c < enumname.size(); c++) + lcenum[c] = std::tolower(enumname[c]); - table.insert(sort_map::value_type(lcenum, i)); + table.insert(sort_map::value_type(lcenum, i)); + } } sort_map::iterator itor; for (itor = table.begin(); itor != table.end(); itor++) { - fprintf(fp, " _tile_pair(\"%s\", %d + %s),\n", + fprintf(fp, " _name_pair(\"%s\", %d + %s),\n", itor->first.c_str(), itor->second, m_start_value.c_str()); } @@ -760,29 +1003,12 @@ bool tile_list_processor::write_data() " for (unsigned int i = 0; i < lc.size(); i++)\n" " lc[i] = tolower(lc[i]);\n" "\n" - " int num_pairs = sizeof(%s_map_pairs) / sizeof(%s_map_pairs[0]);\n" - "\n" - " int first = 0;\n" - " int last = num_pairs - 1;\n" - "\n" - " do\n" - " {\n" - " int half = (last - first) / 2 + first;\n" - " int cmp = strcmp(str, %s_map_pairs[half].first);\n" - " if (cmp < 0)\n" - " last = half - 1;\n" - " else if (cmp > 0)\n" - " first = half + 1;\n" - " else\n" - " {\n" - " idx = %s_map_pairs[half].second;\n" - " return true;\n" - " }\n" "\n" - " } while (first <= last);\n" - "\n" - " return false;\n" - "}\n", - lcname.c_str(), lcname.c_str(), lcname.c_str(), lcname.c_str(), lcname.c_str()); + " int num_pairs = sizeof(%s_name_pairs) / sizeof(%s_name_pairs[0]);\n" + " bool result = binary_search<const char *, unsigned int>(\n" + " lc.c_str(), &%s_name_pairs[0], num_pairs, &strcmp, idx);\n" + " return (result);\n" + "}\n\n", + lcname.c_str(), lcname.c_str(), lcname.c_str(), lcname.c_str()); fprintf(fp, "bool tile_%s_equal(unsigned int tile, unsigned int idx)\n" @@ -792,6 +1018,43 @@ bool tile_list_processor::write_data() "}\n\n", lcname.c_str(), m_start_value.c_str(), max.c_str(), lcname.c_str()); + fprintf(fp, "\ntypedef std::pair<tile_variation, unsigned int> _colour_pair;\n\n"); + + fprintf(fp, + "_colour_pair %s_colour_pairs[] =\n" + "{\n" + " _colour_pair(tile_variation(0, 0), 0),\n", + lcname.c_str()); + + for (unsigned int i = 0; i < m_page.m_tiles.size(); i++) + { + for (int c = 0; c < MAX_COLOUR; ++c) + { + int var; + if (!m_page.m_tiles[i]->get_variation(c, var)) + continue; + + fprintf(fp, + " _colour_pair(tile_variation(%d + %s, %d), %d + %s),\n", + i, m_start_value.c_str(), c, var, m_start_value.c_str()); + } + } + + fprintf(fp, "%s", "};\n\n"); + + fprintf(fp, + "unsigned int tile_%s_coloured(unsigned int idx, int col)\n" + "{\n" + " int num_pairs = sizeof(%s_colour_pairs) / sizeof(%s_colour_pairs[0]);\n" + " tile_variation key(idx, col);\n" + " unsigned int found;\n" + " bool result = binary_search<tile_variation, unsigned int>(\n" + " key, &%s_colour_pairs[0], num_pairs,\n" + " &tile_variation::cmp, found);\n" + " return (result ? found : idx);\n" + "}\n\n", + lcname.c_str(), lcname.c_str(), lcname.c_str(), lcname.c_str()); + fclose(fp); } @@ -818,29 +1081,32 @@ bool tile_list_processor::write_data() fprintf(fp, "<td><img src=\"%s\"/></td>", m_page.m_tiles[i]->filename().c_str()); - std::string lcenum = m_page.m_tiles[i]->enumname(); - for (unsigned int c = 0; c < lcenum.size(); c++) - lcenum[c] = std::tolower(lcenum[c]); - - fprintf(fp, "<td>%s</td>", lcenum.c_str()); - - const std::string &parts_ctg = m_page.m_tiles[i]->parts_ctg(); - if (m_page.m_tiles[i]->enumname().empty()) + if (m_page.m_tiles[i]->enumcount() == 0) { - fprintf(fp, "<td></td>"); - } - else if (parts_ctg.empty()) - { - fprintf(fp, "<td>%s_%s</td>", - m_prefix.c_str(), - m_page.m_tiles[i]->enumname().c_str()); + fprintf(fp, "<td></td><td></td>"); } else { - fprintf(fp, "<td>%s_%s_%s</td>", - m_prefix.c_str(), - parts_ctg.c_str(), - m_page.m_tiles[i]->enumname().c_str()); + std::string lcenum = m_page.m_tiles[i]->enumname(0); + for (unsigned int c = 0; c < lcenum.size(); c++) + lcenum[c] = std::tolower(lcenum[c]); + + fprintf(fp, "<td>%s</td>", lcenum.c_str()); + + const std::string &parts_ctg = m_page.m_tiles[i]->parts_ctg(); + if (parts_ctg.empty()) + { + fprintf(fp, "<td>%s_%s</td>", + m_prefix.c_str(), + m_page.m_tiles[i]->enumname(0).c_str()); + } + else + { + fprintf(fp, "<td>%s_%s_%s</td>", + m_prefix.c_str(), + parts_ctg.c_str(), + m_page.m_tiles[i]->enumname(0).c_str()); + } } fprintf(fp, "<td>%s</td>", m_page.m_tiles[i]->filename().c_str()); diff --git a/crawl-ref/source/rltiles/tool/tile_list_processor.h b/crawl-ref/source/rltiles/tool/tile_list_processor.h index 74b199b5ef..5e95d1815b 100644 --- a/crawl-ref/source/rltiles/tool/tile_list_processor.h +++ b/crawl-ref/source/rltiles/tool/tile_list_processor.h @@ -18,6 +18,7 @@ protected: bool load_image(tile &img, const char *filename); bool process_line(char *read_line, const char *list_file, int line); void add_image(tile &img, const char *enumname); + void recolour(tile &img); std::string m_name; @@ -38,6 +39,22 @@ protected: std::vector<std::string> m_categories; std::vector<int> m_ctg_counts; tile m_compose; + int m_variation_idx; + int m_variation_col; + + typedef std::pair<tile_colour, tile_colour> palette_entry; + typedef std::vector<palette_entry> palette_list; + palette_list m_palette; + + typedef std::pair<int, int> int_pair; + typedef std::vector<int_pair> hue_list; + hue_list m_hues; + + typedef std::vector<int> desat_list; + desat_list m_desat; + + typedef std::vector<int_pair> lum_list; + lum_list m_lum; }; #endif diff --git a/crawl-ref/source/rltiles/tool/tile_page.cc b/crawl-ref/source/rltiles/tool/tile_page.cc index 67c77db3ea..4bd6c8a10f 100644 --- a/crawl-ref/source/rltiles/tool/tile_page.cc +++ b/crawl-ref/source/rltiles/tool/tile_page.cc @@ -88,6 +88,31 @@ bool tile_page::place_images() return (true); } +int tile_page::find(const std::string &enumname) const +{ + for (size_t i = 0; i < m_tiles.size(); ++i) + { + for (int c = 0; c < m_tiles[i]->enumcount(); ++c) + { + if (m_tiles[i]->enumname(c) == enumname) + return (i); + } + } + + return (-1); +} + +bool tile_page::add_synonym(const std::string &enumname, const std::string &syn) +{ + int idx = find(enumname); + if (idx == -1) + return (false); + + m_tiles[idx]->add_enumname(syn); + + return (true); +} + bool tile_page::write_image(const char *filename) { if (m_width * m_height <= 0) @@ -123,3 +148,12 @@ bool tile_page::write_image(const char *filename) delete[] pixels; return success; } + +void tile_page::add_variation(int var_idx, int base_idx, int colour) +{ + assert(var_idx < (2 << 15)); + assert(base_idx < (2 << 15)); + + m_tiles[base_idx]->add_variation(colour, var_idx); +} + diff --git a/crawl-ref/source/rltiles/tool/tile_page.h b/crawl-ref/source/rltiles/tool/tile_page.h index 9f13651a1d..d9f6a47861 100644 --- a/crawl-ref/source/rltiles/tool/tile_page.h +++ b/crawl-ref/source/rltiles/tool/tile_page.h @@ -13,10 +13,15 @@ public: bool place_images(); bool write_image(const char *filename); + int find(const std::string &enumname) const; + bool add_synonym(const std::string &enumname, const std::string &syn); + void add_variation(int var_idx, int base_idx, int colour); + std::vector<tile*> m_tiles; std::vector<unsigned int> m_counts; std::vector<int> m_texcoords; std::vector<int> m_offsets; + protected: int m_width; int m_height; |