|
1 | 1 | package bwapi.values; |
2 | 2 |
|
3 | | -//TODO |
| 3 | + |
| 4 | +import java.util.Objects; |
| 5 | + |
4 | 6 | public class Color { |
5 | | - private final int r, g, b; |
6 | | - public final int value; |
| 7 | + public final int id; |
7 | 8 |
|
8 | 9 | public Color(final int r, final int g, final int b) { |
9 | | - this.r = r; |
10 | | - this.g = g; |
11 | | - this.b = b; |
12 | | - value = 0; |
| 10 | + id = getRGBIndex(r, g, b); |
13 | 11 | } |
14 | 12 |
|
15 | | - public Color(final int value) { |
16 | | - this.r = 0; |
17 | | - this.g = 0; |
18 | | - this.b = 0; |
19 | | - this.value = value; |
| 13 | + public Color(final int id) { |
| 14 | + this.id = id; |
20 | 15 | } |
21 | 16 |
|
22 | | - public static Color Red; |
| 17 | + public final static Color Red = new Color(111); |
23 | 18 |
|
24 | | - public static Color Blue; |
| 19 | + public final static Color Blue = new Color(165); |
25 | 20 |
|
26 | | - public static Color Teal; |
| 21 | + public final static Color Teal = new Color(159); |
27 | 22 |
|
28 | | - public static Color Purple; |
| 23 | + public final static Color Purple = new Color(164); |
29 | 24 |
|
30 | | - public static Color Orange; |
| 25 | + public final static Color Orange = new Color(179); |
31 | 26 |
|
32 | | - public static Color Brown; |
| 27 | + public final static Color Brown = new Color(19); |
33 | 28 |
|
34 | | - public static Color White; |
| 29 | + public final static Color White = new Color(255); |
35 | 30 |
|
36 | | - public static Color Yellow; |
| 31 | + public final static Color Yellow = new Color(135); |
37 | 32 |
|
38 | | - public static Color Green; |
| 33 | + public final static Color Green = new Color(117); |
39 | 34 |
|
40 | | - public static Color Cyan; |
| 35 | + public final static Color Cyan = new Color(128); |
41 | 36 |
|
42 | | - public static Color Black; |
| 37 | + public final static Color Black = new Color(0); |
43 | 38 |
|
44 | | - public static Color Grey; |
| 39 | + public final static Color Grey = new Color(74); |
| 40 | + |
| 41 | + int red() { |
| 42 | + return id < 256 ? defaultPalette[id].rgbRed : 0; |
| 43 | + } |
| 44 | + int green() { |
| 45 | + return id < 256 ? defaultPalette[id].rgbGreen : 0; |
| 46 | + } |
| 47 | + int blue() { |
| 48 | + return id < 256 ? defaultPalette[id].rgbBlue : 0; |
| 49 | + } |
45 | 50 |
|
46 | 51 | @Override |
47 | 52 | public boolean equals(Object o) { |
48 | | - if (!(o instanceof Color)) return false; |
49 | | - |
50 | | - Color color = (Color) o; |
51 | | - |
52 | | - return b == color.b && g != color.g && r != color.r; |
| 53 | + if (!(o instanceof Color)) { |
| 54 | + return false; |
| 55 | + } |
| 56 | + return id == ((Color) o).id; |
53 | 57 | } |
54 | 58 |
|
55 | 59 | @Override |
56 | 60 | public int hashCode() { |
57 | | - int result = r; |
58 | | - result = 31 * result + g; |
59 | | - result = 31 * result + b; |
60 | | - return result; |
| 61 | + return Objects.hash(id); |
| 62 | + } |
| 63 | + |
| 64 | + /// BROODWAR COLOR IMPLEMENTATION |
| 65 | + private static class RGBQUAD { |
| 66 | + byte rgbRed; |
| 67 | + byte rgbGreen; |
| 68 | + byte rgbBlue; |
| 69 | + byte rgbReserved; |
| 70 | + |
| 71 | + RGBQUAD(int rgbRed, int rgbGreen, int rgbBlue) { |
| 72 | + this(rgbRed,rgbGreen, rgbBlue, 0); |
| 73 | + } |
| 74 | + |
| 75 | + RGBQUAD(int rgbRed, int rgbGreen, int rgbBlue, int rgbReserved) { |
| 76 | + this.rgbRed = (byte)rgbRed; |
| 77 | + this.rgbGreen = (byte)rgbGreen; |
| 78 | + this.rgbBlue = (byte)rgbBlue; |
| 79 | + this.rgbReserved = (byte)rgbReserved; |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + private static RGBQUAD RGBRESERVE = new RGBQUAD(0,0,0,0xFF); |
| 84 | + |
| 85 | + private static boolean rgbInitialized = false; |
| 86 | + private static final RGBQUAD defaultPalette[] = { |
| 87 | + new RGBQUAD(0, 0, 0), RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, |
| 88 | + RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, |
| 89 | + new RGBQUAD(24, 36, 44), new RGBQUAD(72, 36, 20), new RGBQUAD(92, 44, 20), new RGBQUAD(112, 48, 20), new RGBQUAD(104, 60, 36), new RGBQUAD(124, 64, 24), new RGBQUAD(120, 76, 44), new RGBQUAD(168, 8, 8), |
| 90 | + new RGBQUAD(140, 84, 48), new RGBQUAD(132, 96, 68), new RGBQUAD(160, 84, 28), new RGBQUAD(196, 76, 24), new RGBQUAD(188, 104, 36), new RGBQUAD(180, 112, 60), new RGBQUAD(208, 100, 32), new RGBQUAD(220, 148, 52), |
| 91 | + new RGBQUAD(224, 148, 84), new RGBQUAD(236, 196, 84), new RGBQUAD(52, 68, 40), new RGBQUAD(64, 108, 60), new RGBQUAD(72, 108, 80), new RGBQUAD(76, 128, 80), new RGBQUAD(80, 140, 92), new RGBQUAD(92, 160, 120), |
| 92 | + new RGBQUAD(0, 0, 24), new RGBQUAD(0, 16, 52), new RGBQUAD(0, 8, 80), new RGBQUAD(36, 52, 72), new RGBQUAD(48, 64, 84), new RGBQUAD(20, 52, 124), new RGBQUAD(52, 76, 108), new RGBQUAD(64, 88, 116), |
| 93 | + new RGBQUAD(72, 104, 140), new RGBQUAD(0, 112, 156), new RGBQUAD(88, 128, 164), new RGBQUAD(64, 104, 212), new RGBQUAD(24, 172, 184), new RGBQUAD(36, 36, 252), new RGBQUAD(100, 148, 188), new RGBQUAD(112, 168, 204), |
| 94 | + new RGBQUAD(140, 192, 216), new RGBQUAD(148, 220, 244), new RGBQUAD(172, 220, 232), new RGBQUAD(172, 252, 252), new RGBQUAD(204, 248, 248), new RGBQUAD(252, 252, 0), new RGBQUAD(244, 228, 144), new RGBQUAD(252, 252, 192), |
| 95 | + new RGBQUAD(12, 12, 12), new RGBQUAD(24, 20, 16), new RGBQUAD(28, 28, 32), new RGBQUAD(40, 40, 48), new RGBQUAD(56, 48, 36), new RGBQUAD(56, 60, 68), new RGBQUAD(76, 64, 48), new RGBQUAD(76, 76, 76), |
| 96 | + new RGBQUAD(92, 80, 64), new RGBQUAD(88, 88, 88), new RGBQUAD(104, 104, 104), new RGBQUAD(120, 132, 108), new RGBQUAD(104, 148, 108), new RGBQUAD(116, 164, 124), new RGBQUAD(152, 148, 140), new RGBQUAD(144, 184, 148), |
| 97 | + new RGBQUAD(152, 196, 168), new RGBQUAD(176, 176, 176), new RGBQUAD(172, 204, 176), new RGBQUAD(196, 192, 188), new RGBQUAD(204, 224, 208), new RGBQUAD(240, 240, 240), new RGBQUAD(28, 16, 8), new RGBQUAD(40, 24, 12), |
| 98 | + new RGBQUAD(52, 16, 8), new RGBQUAD(52, 32, 12), new RGBQUAD(56, 16, 32), new RGBQUAD(52, 40, 32), new RGBQUAD(68, 52, 8), new RGBQUAD(72, 48, 24), new RGBQUAD(96, 0, 0), new RGBQUAD(84, 40, 32), |
| 99 | + new RGBQUAD(80, 64, 20), new RGBQUAD(92, 84, 20), new RGBQUAD(132, 4, 4), new RGBQUAD(104, 76, 52), new RGBQUAD(124, 56, 48), new RGBQUAD(112, 100, 32), new RGBQUAD(124, 80, 80), new RGBQUAD(164, 52, 28), |
| 100 | + new RGBQUAD(148, 108, 0), new RGBQUAD(152, 92, 64), new RGBQUAD(140, 128, 52), new RGBQUAD(152, 116, 84), new RGBQUAD(184, 84, 68), new RGBQUAD(176, 144, 24), new RGBQUAD(176, 116, 92), new RGBQUAD(244, 4, 4), |
| 101 | + new RGBQUAD(200, 120, 84), new RGBQUAD(252, 104, 84), new RGBQUAD(224, 164, 132), new RGBQUAD(252, 148, 104), new RGBQUAD(252, 204, 44), new RGBQUAD(16, 252, 24), new RGBQUAD(12, 0, 32), new RGBQUAD(28, 28, 44), |
| 102 | + new RGBQUAD(36, 36, 76), new RGBQUAD(40, 44, 104), new RGBQUAD(44, 48, 132), new RGBQUAD(32, 24, 184), new RGBQUAD(52, 60, 172), new RGBQUAD(104, 104, 148), new RGBQUAD(100, 144, 252), new RGBQUAD(124, 172, 252), |
| 103 | + new RGBQUAD(0, 228, 252), new RGBQUAD(156, 144, 64), new RGBQUAD(168, 148, 84), new RGBQUAD(188, 164, 92), new RGBQUAD(204, 184, 96), new RGBQUAD(232, 216, 128), new RGBQUAD(236, 196, 176), new RGBQUAD(252, 252, 56), |
| 104 | + new RGBQUAD(252, 252, 124), new RGBQUAD(252, 252, 164), new RGBQUAD(8, 8, 8), new RGBQUAD(16, 16, 16), new RGBQUAD(24, 24, 24), new RGBQUAD(40, 40, 40), new RGBQUAD(52, 52, 52), new RGBQUAD(76, 60, 56), |
| 105 | + new RGBQUAD(68, 68, 68), new RGBQUAD(72, 72, 88), new RGBQUAD(88, 88, 104), new RGBQUAD(116, 104, 56), new RGBQUAD(120, 100, 92), new RGBQUAD(96, 96, 124), new RGBQUAD(132, 116, 116), new RGBQUAD(132, 132, 156), |
| 106 | + new RGBQUAD(172, 140, 124), new RGBQUAD(172, 152, 148), new RGBQUAD(144, 144, 184), new RGBQUAD(184, 184, 232), new RGBQUAD(248, 140, 20), new RGBQUAD(16, 84, 60), new RGBQUAD(32, 144, 112), new RGBQUAD(44, 180, 148), |
| 107 | + new RGBQUAD(4, 32, 100), new RGBQUAD(72, 28, 80), new RGBQUAD(8, 52, 152), new RGBQUAD(104, 48, 120), new RGBQUAD(136, 64, 156), new RGBQUAD(12, 72, 204), new RGBQUAD(188, 184, 52), new RGBQUAD(220, 220, 60), |
| 108 | + new RGBQUAD(16, 0, 0), new RGBQUAD(36, 0, 0), new RGBQUAD(52, 0, 0), new RGBQUAD(72, 0, 0), new RGBQUAD(96, 24, 4), new RGBQUAD(140, 40, 8), new RGBQUAD(200, 24, 24), new RGBQUAD(224, 44, 44), |
| 109 | + new RGBQUAD(232, 32, 32), new RGBQUAD(232, 80, 20), new RGBQUAD(252, 32, 32), new RGBQUAD(232, 120, 36), new RGBQUAD(248, 172, 60), new RGBQUAD(0, 20, 0), new RGBQUAD(0, 40, 0), new RGBQUAD(0, 68, 0), |
| 110 | + new RGBQUAD(0, 100, 0), new RGBQUAD(8, 128, 8), new RGBQUAD(36, 152, 36), new RGBQUAD(60, 156, 60), new RGBQUAD(88, 176, 88), new RGBQUAD(104, 184, 104), new RGBQUAD(128, 196, 128), new RGBQUAD(148, 212, 148), |
| 111 | + new RGBQUAD(12, 20, 36), new RGBQUAD(36, 60, 100), new RGBQUAD(48, 80, 132), new RGBQUAD(56, 92, 148), new RGBQUAD(72, 116, 180), new RGBQUAD(84, 132, 196), new RGBQUAD(96, 148, 212), new RGBQUAD(120, 180, 236), |
| 112 | + RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, |
| 113 | + RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, |
| 114 | + RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, |
| 115 | + RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, |
| 116 | + RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, |
| 117 | + RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, |
| 118 | + RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, RGBRESERVE, new RGBQUAD(255, 255, 255) |
| 119 | + }; |
| 120 | + |
| 121 | + private static int getBestIdFor(int red, int green, int blue) { |
| 122 | + |
| 123 | + int min_dist = 3 * 256 * 256; |
| 124 | + int best_id = 0; |
| 125 | + for( int id = 0; id < 255; ++id ) { |
| 126 | + RGBQUAD p = defaultPalette[id]; |
| 127 | + if (p.rgbReserved != 0) { |
| 128 | + continue; |
| 129 | + } |
| 130 | + int r = red - p.rgbRed; |
| 131 | + int g = green - p.rgbGreen; |
| 132 | + int b = blue - p.rgbBlue; |
| 133 | + |
| 134 | + int distance = r*r + g*g + b*b; |
| 135 | + if ( distance < min_dist ) { |
| 136 | + min_dist = distance; |
| 137 | + best_id = id; |
| 138 | + if (distance == 0) { |
| 139 | + break; |
| 140 | + } |
| 141 | + } |
| 142 | + } |
| 143 | + return best_id; |
| 144 | + } |
| 145 | + |
| 146 | + private static byte closestColor[][][] = new byte[64][64][64]; |
| 147 | + |
| 148 | + private static int getRGBIndex(int red, int green, int blue) { |
| 149 | + if ( !rgbInitialized ) { |
| 150 | + rgbInitialized = true; |
| 151 | + for (int r = 0; r < 64; ++r ) { |
| 152 | + for (int g = 0; g < 64; ++g ) { |
| 153 | + for (int b = 0; b < 64; ++b ) { |
| 154 | + closestColor[r][g][b] = (byte) getBestIdFor(r << 2, g << 2, b << 2); |
| 155 | + } |
| 156 | + } |
| 157 | + } |
| 158 | + } |
| 159 | + return closestColor[(byte)red >> 2][(byte)green >> 2][(byte)blue >> 2]; |
61 | 160 | } |
62 | 161 | } |
0 commit comments