diff --git a/bin/data/cmclient-5.grf b/bin/data/cmclient-5.grf deleted file mode 100644 index 5ba1aaa2da..0000000000 Binary files a/bin/data/cmclient-5.grf and /dev/null differ diff --git a/bin/data/cmclient-6.grf b/bin/data/cmclient-6.grf new file mode 100644 index 0000000000..9577b4c9cf Binary files /dev/null and b/bin/data/cmclient-6.grf differ diff --git a/grf/cmclient/gencmclientgrf.py b/grf/cmclient/gencmclientgrf.py index 19119f4b99..f5d9f180c7 100644 --- a/grf/cmclient/gencmclientgrf.py +++ b/grf/cmclient/gencmclientgrf.py @@ -190,26 +190,9 @@ def gen_oklab_tint(tint, ratio): # (0.7433, 0, 0.15) # (0.7418, -0.09, 0.15) - remap = lambda f: g.add(grf.PaletteRemap.oklab_from_function(f, remap_range=grf.ALL_COLOURS)) -remap(gen_tint((1, 0, 0), 0.6)) # deep red tint -remap(gen_tint((1, 0.5, 0), 0.65)) # deep orange tint -remap(gen_tint((0, 1, 0), 0.65)) # deep green tint -remap(gen_tint((0, 1, 1), 0.65)) # deep cyan tint -remap(gen_tint((1, 0, 0), 0.4)) # red tint -remap(gen_tint((1, 0.5, 0), 0.4)) # orange tint -remap(gen_tint((1.0, 1.0, 0), 0.4)) # yellow tint -# remap(gen_oklab_tint((0.5498, 0.17, 0.1), 0.5)) # red tint -# remap(gen_oklab_tint((0.7433, 0.09, 0.15), 0.5)) # orange tint -# remap(gen_oklab_tint((0.7433, 0, 0.15), 0.5)) # yellow tint -remap(gen_tint((1.0, 1.0, 0.5), 0.4)) # yellow white tint -remap(gen_white_tint_contrast()) # white tint -# remap(gen_oklab_tint((0.7418, -0.09, 0.15), 0.5)) # white tint -remap(gen_tint((0, 1.0, 0), 0.4)) # green tint -remap(gen_tint((0, 1.0, 1.0), 0.4)) # cyan tint -remap(gen_tint((0.5, 1.0, 1.0), 0.4)) # cyan white tint -remap(gen_tint((0, 0, 1.0), 0.4)) # blue tint +# Tree shades B = 22.2 remap(gen_brightness(21.7 - B)) # shade N remap(gen_brightness(24.2 - B)) # shade NE 27.2 @@ -220,7 +203,35 @@ remap(gen_brightness(18.4 - B)) # shade SW remap(gen_brightness(17.1 - B)) # shade W remap(gen_brightness(17.5 - B)) # shade NW -grf.main(g, '../../bin/data/cmclient-5.grf') +BASE_TINTS = { + 'red_deep': gen_tint((1, 0, 0), 0.6), + 'orange_deep': gen_tint((1, 0.5, 0), 0.65), + #'green_deep': gen_tint((0, 1, 0), 0.65), + #'cyan_deep': gen_tint((0, 1, 1), 0.65), + 'red': gen_tint((1, 0, 0), 0.4), + 'orange': gen_tint((1, 0.5, 0), 0.4), + 'yellow': gen_tint((1.0, 1.0, 0), 0.4), + 'white': gen_white_tint_contrast(), + 'green': gen_tint((0, 1.0, 0), 0.4), + 'cyan': gen_tint((0, 1.0, 1.0), 0.4), + 'blue': gen_tint((0, 0, 1.0), 0.4), +} +# remap(gen_tint((0.5, 1.0, 1.0), 0.4)) # cyan white tint + +for f in BASE_TINTS.values(): + remap(f) + +for f1 in BASE_TINTS.values(): + for f2 in BASE_TINTS.values(): + remap(lambda x: f2(f1(x))) + +# Only white can be mixed over any combination +white = BASE_TINTS['white'] +for f1 in BASE_TINTS.values(): + for f2 in BASE_TINTS.values(): + remap(lambda x: white(f2(f1(x)))) + +grf.main(g, '../../bin/data/cmclient-6.grf') # func = gen_brightness(17.1 - B) # grf.make_palette_image([grf.oklab_to_srgb(func(x)) for x in grf.OKLAB_PALETTE]).show() diff --git a/src/citymania/cm_highlight.cpp b/src/citymania/cm_highlight.cpp index b30067f722..aa623dbe64 100644 --- a/src/citymania/cm_highlight.cpp +++ b/src/citymania/cm_highlight.cpp @@ -1035,12 +1035,44 @@ void HighlightMap::AddTilesBorder(const std::set &tiles, SpriteID pal } } +SpriteID MixTints(SpriteID bottom, SpriteID top) { + if (top == PAL_NONE) return bottom; + if (bottom == PAL_NONE) return top; + assert (bottom >= CM_PALETTE_TINT_BASE && bottom < CM_PALETTE_TINT_END); + assert (top >= CM_PALETTE_TINT_BASE && top < CM_PALETTE_TINT_MIXES); + if (bottom < CM_PALETTE_TINT_MIXES) { + // Single tint -> use mixed + return ( + CM_PALETTE_TINT_MIXES + + (bottom - CM_PALETTE_TINT_BASE) * CM_PALETTE_TINT_BASE_COUNT + + (top - CM_PALETTE_TINT_BASE) + ); + } + // White mix can't be mixed again + if (bottom >= CM_PALETTE_TINT_MIXES_WHITE) { + Debug(misc, 0, "White highlights can't be stacked"); + return bottom; + } + if (top == CM_PALETTE_TINT_WHITE) { + // Use same mix but in the white range + return bottom - CM_PALETTE_TINT_MIXES + CM_PALETTE_TINT_MIXES_WHITE; + } + + // Mix two last tints + auto last_mixed = (bottom - CM_PALETTE_TINT_MIXES) % CM_PALETTE_TINT_BASE_COUNT; + return ( + CM_PALETTE_TINT_MIXES + + last_mixed * CM_PALETTE_TINT_BASE_COUNT + + (top - CM_PALETTE_TINT_BASE) + ); +} + SpriteID GetTintBySelectionColour(SpriteID colour, bool deep=false) { switch(colour) { case CM_SPR_PALETTE_ZONING_RED: return (deep ? CM_PALETTE_TINT_RED_DEEP : CM_PALETTE_TINT_RED); case CM_SPR_PALETTE_ZONING_ORANGE: return (deep ? CM_PALETTE_TINT_ORANGE_DEEP : CM_PALETTE_TINT_ORANGE); - case CM_SPR_PALETTE_ZONING_GREEN: return (deep ? CM_PALETTE_TINT_GREEN_DEEP : CM_PALETTE_TINT_GREEN); - case CM_SPR_PALETTE_ZONING_LIGHT_BLUE: return (deep ? CM_PALETTE_TINT_CYAN_DEEP : CM_PALETTE_TINT_CYAN); + case CM_SPR_PALETTE_ZONING_GREEN: return CM_PALETTE_TINT_GREEN; + case CM_SPR_PALETTE_ZONING_LIGHT_BLUE: return CM_PALETTE_TINT_CYAN; case CM_SPR_PALETTE_ZONING_YELLOW: return CM_PALETTE_TINT_YELLOW; // case SPR_PALETTE_ZONING__: return PALETTE_TINT_YELLOW_WHITE; case CM_SPR_PALETTE_ZONING_WHITE: return CM_PALETTE_TINT_WHITE; @@ -1056,10 +1088,8 @@ SpriteID GetSelectionColourByTint(SpriteID colour) { case CM_PALETTE_TINT_ORANGE_DEEP: case CM_PALETTE_TINT_ORANGE: return CM_SPR_PALETTE_ZONING_ORANGE; - case CM_PALETTE_TINT_GREEN_DEEP: case CM_PALETTE_TINT_GREEN: return CM_SPR_PALETTE_ZONING_GREEN; - case CM_PALETTE_TINT_CYAN_DEEP: case CM_PALETTE_TINT_CYAN: return CM_SPR_PALETTE_ZONING_LIGHT_BLUE; case CM_PALETTE_TINT_YELLOW: @@ -2240,8 +2270,9 @@ TileHighlight GetTileHighlight(const TileInfo *ti, TileType tile_type) { auto hl = _at.tiles.GetForTile(ti->tile); if (hl.has_value()) { - for (auto &oth : hl.value().get()) { + for (auto &oth : hl->get()) { oth.SetTileHighlight(th, ti); + Debug(misc, 0, "GetTileHighlight {} {}:{}", ti->tile, oth.type, th.structure_pal == CM_PALETTE_HIDE_SPRITE); } return th; } diff --git a/src/citymania/cm_highlight.hpp b/src/citymania/cm_highlight.hpp index 45e48754f2..7f8ee3df18 100644 --- a/src/citymania/cm_highlight.hpp +++ b/src/citymania/cm_highlight.hpp @@ -29,6 +29,7 @@ namespace citymania { // MEDIUM = 2, // SMALL = 3, // }; +SpriteID MixTints(SpriteID bottom, SpriteID top); TileHighlight GetTileHighlight(const TileInfo *ti, TileType tile_type); void DrawTileZoning(const TileInfo *ti, const TileHighlight &th, TileType tile_type); diff --git a/src/citymania/cm_station_gui.cpp b/src/citymania/cm_station_gui.cpp index 0a180fafcb..a0af544c17 100644 --- a/src/citymania/cm_station_gui.cpp +++ b/src/citymania/cm_station_gui.cpp @@ -702,7 +702,7 @@ static HighlightMap PrepareHighilightMap(Station *st_join, std::optionalcatchment_tiles) { - auto pal = join_area.Contains(t) ? CM_PALETTE_TINT_CYAN_WHITE : CM_PALETTE_TINT_WHITE; + auto pal = join_area.Contains(t) ? MixTints(CM_PALETTE_TINT_CYAN, CM_PALETTE_TINT_WHITE) : CM_PALETTE_TINT_WHITE; hlmap.Add(t, ObjectTileHighlight::make_tint(pal)); coverage_area.insert(t); } @@ -720,7 +720,7 @@ static HighlightMap PrepareHighilightMap(Station *st_join, std::optional= CM_PALETTE_TINT_BASE && pal < CM_PALETTE_TINT_END) + return CM_BM_TINT_REMAP; + switch (pal) { case PAL_NONE: return BM_NORMAL; case PALETTE_CRASH: return BM_CRASH_REMAP; case PALETTE_ALL_BLACK: return BM_BLACK_REMAP; - - case CM_PALETTE_TINT_RED_DEEP: - case CM_PALETTE_TINT_ORANGE_DEEP: - case CM_PALETTE_TINT_GREEN_DEEP: - case CM_PALETTE_TINT_CYAN_DEEP: - case CM_PALETTE_TINT_RED: - case CM_PALETTE_TINT_ORANGE: - case CM_PALETTE_TINT_YELLOW: - case CM_PALETTE_TINT_YELLOW_WHITE: - case CM_PALETTE_TINT_WHITE: - case CM_PALETTE_TINT_GREEN: - case CM_PALETTE_TINT_CYAN: - case CM_PALETTE_TINT_CYAN_WHITE: - case CM_PALETTE_TINT_BLUE: - case CM_PALETTE_SHADE_N: - case CM_PALETTE_SHADE_NE: - case CM_PALETTE_SHADE_E: - case CM_PALETTE_SHADE_SE: - case CM_PALETTE_SHADE_S: - case CM_PALETTE_SHADE_SW: - case CM_PALETTE_SHADE_W: - case CM_PALETTE_SHADE_NW: - case CM_PALETTE_TINT_COUNT: - return CM_BM_TINT_REMAP; - default: return BM_COLOUR_REMAP; } } diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp index f4af3dc6d4..cf3fbd2e4f 100644 --- a/src/gfxinit.cpp +++ b/src/gfxinit.cpp @@ -174,7 +174,7 @@ static void LoadSpriteTables() PAL_DOS != used_set->palette ); } - LoadGrfFile("cmclient-5.grf", CM_SPR_CITYMANIA_BASE, PAL_DOS != used_set->palette); + LoadGrfFile("cmclient-6.grf", CM_SPR_CITYMANIA_BASE, PAL_DOS != used_set->palette); /* Initialize the unicode to sprite mapping table */ InitializeUnicodeGlyphMap(); diff --git a/src/table/sprites.h b/src/table/sprites.h index 374c999f7d..f2792950c1 100644 --- a/src/table/sprites.h +++ b/src/table/sprites.h @@ -337,30 +337,38 @@ static const SpriteID CM_SPR_INNER_HIGHLIGHT_COUNT = 30; static const SpriteID CM_SPR_BORDER_HIGHLIGHT_BASE = CM_SPR_INNER_HIGHLIGHT_BASE + CM_SPR_INNER_HIGHLIGHT_COUNT; static const SpriteID CM_SPR_BORDER_HIGHLIGHT_COUNT = 19 * 19; -static const SpriteID CM_PALETTE_TINT_BASE = CM_SPR_BORDER_HIGHLIGHT_BASE + CM_SPR_BORDER_HIGHLIGHT_COUNT; + +/* Tree shades */ +static const SpriteID CM_PALETTE_SHADE_BASE = CM_SPR_BORDER_HIGHLIGHT_BASE + CM_SPR_BORDER_HIGHLIGHT_COUNT; +static const SpriteID CM_PALETTE_SHADE_N = CM_PALETTE_SHADE_BASE; +static const SpriteID CM_PALETTE_SHADE_NE = CM_PALETTE_SHADE_BASE + 1; +static const SpriteID CM_PALETTE_SHADE_E = CM_PALETTE_SHADE_BASE + 2; +static const SpriteID CM_PALETTE_SHADE_SE = CM_PALETTE_SHADE_BASE + 3; +static const SpriteID CM_PALETTE_SHADE_S = CM_PALETTE_SHADE_BASE + 4; +static const SpriteID CM_PALETTE_SHADE_SW = CM_PALETTE_SHADE_BASE + 5; +static const SpriteID CM_PALETTE_SHADE_W = CM_PALETTE_SHADE_BASE + 6; +static const SpriteID CM_PALETTE_SHADE_NW = CM_PALETTE_SHADE_BASE + 7; + +/* Tint remaps */ +static const SpriteID CM_PALETTE_TINT_BASE = CM_PALETTE_SHADE_BASE + 8; static const SpriteID CM_PALETTE_TINT_RED_DEEP = CM_PALETTE_TINT_BASE; static const SpriteID CM_PALETTE_TINT_ORANGE_DEEP = CM_PALETTE_TINT_BASE + 1; -static const SpriteID CM_PALETTE_TINT_GREEN_DEEP = CM_PALETTE_TINT_BASE + 2; -static const SpriteID CM_PALETTE_TINT_CYAN_DEEP = CM_PALETTE_TINT_BASE + 3; -static const SpriteID CM_PALETTE_TINT_RED = CM_PALETTE_TINT_BASE + 4; -static const SpriteID CM_PALETTE_TINT_ORANGE = CM_PALETTE_TINT_BASE + 5; -static const SpriteID CM_PALETTE_TINT_YELLOW = CM_PALETTE_TINT_BASE + 6; -static const SpriteID CM_PALETTE_TINT_YELLOW_WHITE = CM_PALETTE_TINT_BASE + 7; -static const SpriteID CM_PALETTE_TINT_WHITE = CM_PALETTE_TINT_BASE + 8; -static const SpriteID CM_PALETTE_TINT_GREEN = CM_PALETTE_TINT_BASE + 9; -static const SpriteID CM_PALETTE_TINT_CYAN = CM_PALETTE_TINT_BASE + 10; -static const SpriteID CM_PALETTE_TINT_CYAN_WHITE = CM_PALETTE_TINT_BASE + 11; -static const SpriteID CM_PALETTE_TINT_BLUE = CM_PALETTE_TINT_BASE + 12; -static const SpriteID CM_PALETTE_SHADE_N = CM_PALETTE_TINT_BASE + 13; -static const SpriteID CM_PALETTE_SHADE_NE = CM_PALETTE_TINT_BASE + 14; -static const SpriteID CM_PALETTE_SHADE_E = CM_PALETTE_TINT_BASE + 15; -static const SpriteID CM_PALETTE_SHADE_SE = CM_PALETTE_TINT_BASE + 16; -static const SpriteID CM_PALETTE_SHADE_S = CM_PALETTE_TINT_BASE + 17; -static const SpriteID CM_PALETTE_SHADE_SW = CM_PALETTE_TINT_BASE + 18; -static const SpriteID CM_PALETTE_SHADE_W = CM_PALETTE_TINT_BASE + 19; -static const SpriteID CM_PALETTE_SHADE_NW = CM_PALETTE_TINT_BASE + 20; -static const SpriteID CM_PALETTE_TINT_COUNT = 13 + 8; +static const SpriteID CM_PALETTE_TINT_RED = CM_PALETTE_TINT_BASE + 2; +static const SpriteID CM_PALETTE_TINT_ORANGE = CM_PALETTE_TINT_BASE + 3; +static const SpriteID CM_PALETTE_TINT_YELLOW = CM_PALETTE_TINT_BASE + 4; +static const SpriteID CM_PALETTE_TINT_WHITE = CM_PALETTE_TINT_BASE + 5; +static const SpriteID CM_PALETTE_TINT_GREEN = CM_PALETTE_TINT_BASE + 6; +static const SpriteID CM_PALETTE_TINT_CYAN = CM_PALETTE_TINT_BASE + 7; +static const SpriteID CM_PALETTE_TINT_BLUE = CM_PALETTE_TINT_BASE + 8; +static const SpriteID CM_PALETTE_TINT_BASE_COUNT = 9; +static const SpriteID CM_PALETTE_TINT_MIXES = CM_PALETTE_TINT_BASE + CM_PALETTE_TINT_BASE_COUNT; +static const SpriteID CM_PALETTE_TINT_MIXES_WHITE = CM_PALETTE_TINT_BASE + CM_PALETTE_TINT_BASE_COUNT + CM_PALETTE_TINT_BASE_COUNT * CM_PALETTE_TINT_BASE_COUNT; +static const SpriteID CM_PALETTE_TINT_COUNT = CM_PALETTE_TINT_BASE_COUNT + 2 * CM_PALETTE_TINT_BASE_COUNT * CM_PALETTE_TINT_BASE_COUNT; + +/* Special flag to hide sprite */ static const SpriteID CM_PALETTE_HIDE_SPRITE = CM_PALETTE_TINT_BASE + CM_PALETTE_TINT_COUNT; +static const SpriteID CM_PALETTE_TINT_END = CM_PALETTE_HIDE_SPRITE; + /* From where can we start putting NewGRFs? */ static const SpriteID SPR_NEWGRFS_BASE = CM_PALETTE_TINT_BASE + CM_PALETTE_TINT_COUNT + 1;