/* * Icon generation helpers for slide puzzle game * Copyright © 2022-2023 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "colour.h" #include "icon.h" #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define primary(c) (((c) >> 8*COLOUR_PRIMARY) & 0xff) #define dark(c) (((c) >> 8*COLOUR_DARK) & 0xff) #define light(c) (((c) >> 8*COLOUR_LIGHT) & 0xff) static void format_row(unsigned char *row, unsigned long c, unsigned s, unsigned y, unsigned w, unsigned h) { memset(row, dark(c), w); memset(row, primary(c), y+s < h ? w-s : 0); memset(row, light(c), y >= s ? MIN(s, h-y) : w-y); } static void format_row2(unsigned char *row, unsigned long c, unsigned s, unsigned y, unsigned w, unsigned h, unsigned stride) { row += stride*y; if (y > s && y+s < h) { if (stride) memcpy(row, row-stride, w); } else { format_row(row, c, s, y, w, h); } } /* * The 16x16 icon is drawn with 1px shadow, 6x6 tiles, with 1 pixel cropped * off all the edge tiles. */ void icon_tile16(unsigned char *icon, unsigned long c, int tile_x, int tile_y) { unsigned char row[6]; unsigned y, w; icon += 16*(11u*tile_y / 2) + (11u*tile_x / 2); w = 5+(tile_x&1u); for (y = !tile_y; y < 6-(tile_y==2); y++) { format_row2(row, c, 1, y, 6, 6, 0); memcpy(&icon[16*(y-!tile_y)], &row[!tile_x], w); } } /* * The 24x24 icon is drawn with 1px shadow and 8x8 tiles. */ void icon_tile24(unsigned char *icon, unsigned long c, int tile_x, int tile_y) { unsigned y; icon += 8*(24u*tile_y + tile_x); for (y = 0; y < 8; y++) { format_row2(icon, c, 1, y, 8, 8, 24); } } /* * The 32x32 icon is drawn with 1px shadow with slightly uneven tiles on * an 11-10-11 pixel grid. */ void icon_tile32(unsigned char *icon, unsigned long c, int tile_x, int tile_y) { unsigned y, w, h; icon += 32*(10u*tile_y + !!tile_y) + (10u*tile_x + !!tile_x); w = 10u + (tile_x != 1); h = 10u + (tile_y != 1); for (y = 0; y < h; y++) { format_row2(icon, c, 1, y, w, h, 32); } } /* * The 48x48 icon is drawn with 2px shadow and 16x16 tiles. */ void icon_tile48(unsigned char *icon, unsigned long c, int tile_x, int tile_y) { unsigned y; icon += 16*(48u*tile_y + tile_x); for (y = 0; y < 16; y++) { format_row2(icon, c, 2, y, 16, 16, 48); } }