1 /* BurrTools
2  *
3  * BurrTools is the legal property of its developers, whose
4  * names are listed in the COPYRIGHT file, which is included
5  * within the source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11 
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16 
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  */
21 #include "piececolor.h"
22 
23 #include <math.h>
24 
25 #define COLS 18
26 
27 // the table for the first COLS fixed defined colours
28 static float r[COLS] = {
29   0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.6f,
30   0.0f, 0.6f, 0.6f, 0.0f, 0.6f, 0.0f, 0.6f, 1.0f, 1.0f
31 };
32 static float g[COLS] = {
33   0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.6f, 0.0f,
34   0.6f, 0.6f, 0.0f, 1.0f, 1.0f, 0.6f, 0.0f, 0.6f, 0.0f
35 };
36 static float b[COLS] = {
37   1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.6f, 0.0f, 0.0f,
38   0.6f, 0.0f, 0.6f, 0.6f, 0.0f, 1.0f, 1.0f, 0.0f, 0.6f
39 };
40 
41 #define JITTERS 53
42 
43 // the table with the modification values for the multi-pieces
44 static float jr[JITTERS] = {
45    0.0f,
46   -0.3f,  0.3f, -0.3f,  0.3f, -0.3f,  0.3f, -0.3f,  0.3f,  0.3f,
47   -0.3f, -0.3f,  0.3f,  0.3f, -0.3f, -0.3f,  0.3f,  0.0f,  0.0f,
48    0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.3f, -0.3f,
49   -0.4f,  0.4f, -0.4f,  0.4f, -0.4f,  0.4f, -0.4f,  0.4f,  0.4f,
50   -0.4f, -0.4f,  0.4f,  0.4f, -0.4f, -0.4f,  0.4f,  0.0f,  0.0f,
51    0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.4f, -0.4f
52 };
53 static float jg[JITTERS] = {
54    0.0f,
55   -0.3f,  0.3f,  0.3f, -0.3f, -0.3f,  0.3f,  0.3f, -0.3f,  0.3f,
56   -0.3f,  0.3f, -0.3f,  0.0f,  0.0f,  0.0f,  0.0f,  0.3f, -0.3f,
57   -0.3f,  0.3f,  0.0f,  0.0f,  0.3f, -0.3f,  0.0f,  0.0f,
58   -0.4f,  0.4f,  0.4f, -0.4f, -0.4f,  0.4f,  0.4f, -0.4f,  0.4f,
59   -0.4f,  0.4f, -0.4f,  0.0f,  0.0f,  0.0f,  0.0f,  0.4f, -0.4f,
60   -0.4f,  0.4f,  0.0f,  0.0f,  0.4f, -0.4f,  0.0f,  0.0f
61 };
62 static float jb[JITTERS] = {
63    0.0f,
64   -0.3f,  0.3f,  0.3f, -0.3f,  0.3f, -0.3f, -0.3f,  0.3f,  0.0f,
65    0.0f,  0.0f,  0.0f,  0.3f, -0.3f,  0.3f, -0.3f,  0.3f, -0.3f,
66    0.3f, -0.3f,  0.3f, -0.3f,  0.0f,  0.0f,  0.0f,  0.0f,
67   -0.4f,  0.4f,  0.4f, -0.4f,  0.4f, -0.4f, -0.4f,  0.4f,  0.0f,
68    0.0f,  0.0f,  0.0f,  0.4f, -0.4f,  0.4f, -0.4f,  0.4f, -0.4f,
69    0.4f, -0.4f,  0.4f, -0.4f,  0.0f,  0.0f,  0.0f,  0.0f
70 };
71 
pieceColorR(int x)72 float pieceColorR(int x) {
73   if (x < COLS)
74     return r[x];
75   else
76     return float((1+sin(0.7*x))/2);
77 }
78 
pieceColorG(int x)79 float pieceColorG(int x) {
80   if (x < COLS)
81     return g[x];
82   else
83     return float((1+sin(1.3*x+1.5))/2);
84 }
85 
pieceColorB(int x)86 float pieceColorB(int x) {
87   if (x < COLS)
88     return b[x];
89   else
90     return float((1+sin(3.5*x+2.3))/2);
91 }
92 
pieceColorRi(int x)93 unsigned int pieceColorRi(int x) {
94   if (x < COLS)
95     return (unsigned int)(r[x]*255);
96   else
97     return (unsigned int)(255*(1+sin(0.7*x))/2);
98 }
99 
pieceColorGi(int x)100 unsigned int pieceColorGi(int x) {
101   if (x < COLS)
102     return (unsigned int)(g[x]*255);
103   else
104     return (unsigned int)(255*(1+sin(1.3*x+1.5))/2);
105 }
106 
pieceColorBi(int x)107 unsigned int pieceColorBi(int x) {
108   if (x < COLS)
109     return (unsigned int)(b[x]*255);
110   else
111     return (unsigned int)(255*(1+sin(3.5*x+2.3))/2);
112 }
113 
114 
115 /* the problem is that simply adding the jitter
116  * would cause an overflow every now and then, so we
117  * search in the list of possible jitter values
118  * for the x-th with no overflow
119  * when the table is exhausted, we simple do no
120  * jittering any longer
121  */
getJitter(int val,int sub)122 static int getJitter(int val, int sub) {
123   int j = 0;
124   float x;
125 
126   while (j < JITTERS) {
127     x = pieceColorR(val) + jr[j];
128     if ((x < 0) || (x > 1)) {
129       j++;
130       continue;
131     }
132     x = pieceColorG(val) + jg[j];
133     if ((x < 0) || (x > 1)) {
134       j++;
135       continue;
136     }
137     x = pieceColorB(val) + jb[j];
138     if ((x < 0) || (x > 1)) {
139       j++;
140       continue;
141     }
142 
143     if (sub == 0)
144       break;
145 
146     sub--;
147     j++;
148   }
149 
150   if (j == JITTERS) j = 0;
151 
152   return j;
153 }
154 
ramp(float val)155 static float ramp(float val) {
156   return 0.5+0.5*fabs(1-2*val);
157 }
158 
pieceColorR(int x,int sub)159 float pieceColorR(int x, int sub) {
160 
161   float jitter = jr[getJitter(x, sub)];
162   float val = pieceColorR(x);
163 
164   return val + jitter*0.5*ramp(val);
165 }
166 
pieceColorG(int x,int sub)167 float pieceColorG(int x, int sub) {
168 
169   float jitter = jg[getJitter(x, sub)];
170   float val = pieceColorG(x);
171 
172   return val + jitter*0.4*ramp(val);
173 }
174 
pieceColorB(int x,int sub)175 float pieceColorB(int x, int sub) {
176 
177   float jitter = jb[getJitter(x, sub)];
178   float val = pieceColorB(x);
179 
180   return val + jitter*0.7*ramp(val);
181 }
182 
pieceColorRi(int x,int sub)183 unsigned int pieceColorRi(int x, int sub) {
184 
185   float jitter = jr[getJitter(x, sub)];
186   float val = pieceColorR(x);
187 
188   return (unsigned int)((val + jitter*0.5*ramp(val))*255);
189 }
190 
pieceColorGi(int x,int sub)191 unsigned int pieceColorGi(int x, int sub) {
192 
193   float jitter = jg[getJitter(x, sub)];
194   float val = pieceColorG(x);
195 
196   return (unsigned int)((val + jitter*0.4*ramp(val))*255);
197 }
198 
pieceColorBi(int x,int sub)199 unsigned int pieceColorBi(int x, int sub) {
200 
201   float jitter = jb[getJitter(x, sub)];
202   float val = pieceColorB(x);
203 
204   return (unsigned int)((val + jitter*0.7*ramp(val))*255);
205 }
206 
darkPieceColor(float f)207 float darkPieceColor(float f) { return float(f * 0.9); }
lightPieceColor(float f)208 float lightPieceColor(float f) { return float(1 - (0.9 * (1-f))); }
209 
contrastPieceColor(int x)210 Fl_Color contrastPieceColor(int x) {
211   if (3*pieceColorRi(x) + 6*pieceColorGi(x) + pieceColorBi(x) < 1275)
212     return fl_rgb_color(255, 255, 255);
213   else
214     return fl_rgb_color(0, 0, 0);
215 }
216 
217 
218