Subversion Repositories eduke32

Rev

Rev 584 | Rev 1105 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
854 hnt_ts 1
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
2
// Ken Silverman's official web site: "http://www.advsys.net/ken"
3
// See the included license file "BUILDLIC.TXT" for license info.
4
//
5
// This file has been modified from Ken Silverman's original release
6
// by Jonathon Fowler (jonof@edgenetwk.com)
7
 
8
#include "compat.h"
9
#include "pragmas.h"
10
 
11
#define MAXPALOOKUPS 256
12
 
13
static int numpalookups, transratio;
14
static char palettefilename[13], origpalookup[MAXPALOOKUPS<<8];
15
static char palette[768], palookup[MAXPALOOKUPS<<8], transluc[65536];
16
static char closestcol[64][64][64];
17
 
18
#define FASTPALGRIDSIZ 8
19
static int rdist[129], gdist[129], bdist[129];
20
static char colhere[((FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2))>>3];
21
static char colhead[(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)];
22
static int colnext[256];
23
static char coldist[8] = {0,1,2,3,4,3,2,1};
24
static int colscan[27];
25
 
26
 
27
 
28
char getclosestcol(int r, int g, int b)
29
{
30
        int i, j, k, dist, mindist, retcol;
31
        int *rlookup, *glookup, *blookup;
32
        char *ptr;
33
 
34
        if (closestcol[r][g][b] != 255) return(closestcol[r][g][b]);
35
 
36
        j = (r>>3)*FASTPALGRIDSIZ*FASTPALGRIDSIZ+(g>>3)*FASTPALGRIDSIZ+(b>>3)+FASTPALGRIDSIZ*FASTPALGRIDSIZ+FASTPALGRIDSIZ+1;
37
        mindist = min(rdist[coldist[r&7]+64+8],gdist[coldist[g&7]+64+8]);
38
        mindist = min(mindist,bdist[coldist[b&7]+64+8]);
39
        mindist++;
40
 
41
        rlookup = (int *)&rdist[64-r];
42
        glookup = (int *)&gdist[64-g];
43
        blookup = (int *)&bdist[64-b];
44
 
45
        retcol = -1;
46
        for(k=26;k>=0;k--)
47
        {
48
                i = colscan[k]+j; if ((colhere[i>>3]&(1<<(i&7))) == 0) continue;
49
                for(i=colhead[i];i>=0;i=colnext[i])
50
                {
51
                        ptr = (char *)&palette[i*3];
52
                        dist = glookup[ptr[1]]; if (dist >= mindist) continue;
53
                        dist += rlookup[ptr[0]]; if (dist >= mindist) continue;
54
                        dist += blookup[ptr[2]]; if (dist >= mindist) continue;
55
                        mindist = dist; retcol = i;
56
                }
57
        }
58
        if (retcol < 0)
59
        {
60
                mindist = 0x7fffffff;
61
                ptr = (char *)&palette[768-3];
62
                for(i=255;i>=0;i--,ptr-=3)
63
                {
64
                        dist = glookup[ptr[1]]; if (dist >= mindist) continue;
65
                        dist += rlookup[ptr[0]]; if (dist >= mindist) continue;
66
                        dist += blookup[ptr[2]]; if (dist >= mindist) continue;
67
                        mindist = dist; retcol = i;
68
                }
69
        }
70
        ptr = (char *)&closestcol[r][g][b];
71
        *ptr = retcol;
72
        if ((r >= 4) && (ptr[(-2)<<12] == retcol)) ptr[(-3)<<12] = retcol, ptr[(-2)<<12] = retcol, ptr[(-1)<<12] = retcol;
73
        if ((g >= 4) && (ptr[(-2)<<6] == retcol)) ptr[(-3)<<6] = retcol, ptr[(-2)<<6] = retcol, ptr[(-1)<<6] = retcol;
74
        if ((b >= 4) && (ptr[(-2)] == retcol)) ptr[(-3)] = retcol, ptr[(-2)] = retcol, ptr[(-1)] = retcol;
75
        if ((r < 64-4) && (ptr[(2)<<12] == retcol)) ptr[(3)<<12] = retcol, ptr[(2)<<12] = retcol, ptr[(1)<<12] = retcol;
76
        if ((g < 64-4) && (ptr[(2)<<6] == retcol)) ptr[(3)<<6] = retcol, ptr[(2)<<6] = retcol, ptr[(1)<<6] = retcol;
77
        if ((b < 64-4) && (ptr[(2)] == retcol)) ptr[(3)] = retcol, ptr[(2)] = retcol, ptr[(1)] = retcol;
78
        if ((r >= 2) && (ptr[(-1)<<12] == retcol)) ptr[(-1)<<12] = retcol;
79
        if ((g >= 2) && (ptr[(-1)<<6] == retcol)) ptr[(-1)<<6] = retcol;
80
        if ((b >= 2) && (ptr[(-1)] == retcol)) ptr[(-1)] = retcol;
81
        if ((r < 64-2) && (ptr[(1)<<12] == retcol)) ptr[(1)<<12] = retcol;
82
        if ((g < 64-2) && (ptr[(1)<<6] == retcol)) ptr[(1)<<6] = retcol;
83
        if ((b < 64-2) && (ptr[(1)] == retcol)) ptr[(1)] = retcol;
84
        return(retcol);
85
}
86
 
87
char getpalookup(char dashade, char dacol)
88
{
89
        int r, g, b, t;
90
        char *ptr;
91
 
92
        ptr = (char *)&palette[dacol*3];
93
        t = divscale16(numpalookups-dashade,numpalookups);
94
        r = ((ptr[0]*t+32768)>>16);
95
        g = ((ptr[1]*t+32768)>>16);
96
        b = ((ptr[2]*t+32768)>>16);
97
        return(getclosestcol(r,g,b));
98
}
99
 
100
char gettrans(char dat1, char dat2, int datransratio)
101
{
102
        int r, g, b;
103
        char *ptr, *ptr2;
104
 
105
        ptr = (char *)&palette[dat1*3];
106
        ptr2 = (char *)&palette[dat2*3];
107
        r = ptr[0]; r += (((ptr2[0]-r)*datransratio+128)>>8);
108
        g = ptr[1]; g += (((ptr2[1]-g)*datransratio+128)>>8);
109
        b = ptr[2]; b += (((ptr2[2]-b)*datransratio+128)>>8);
110
        return(getclosestcol(r,g,b));
111
}
112
 
113
void initfastcolorlookup(int rscale, int gscale, int bscale)
114
{
115
        int i, j, x, y, z;
116
        char *ptr;
117
 
118
        j = 0;
119
        for(i=64;i>=0;i--)
120
        {
121
                //j = (i-64)*(i-64);
122
                rdist[i] = rdist[128-i] = j*rscale;
123
                gdist[i] = gdist[128-i] = j*gscale;
124
                bdist[i] = bdist[128-i] = j*bscale;
125
                j += 129-(i<<1);
126
        }
127
 
128
        clearbufbyte(FP_OFF(colhere),sizeof(colhere),0L);
129
        clearbufbyte(FP_OFF(colhead),sizeof(colhead),0L);
130
 
131
        ptr = (char *)&palette[768-3];
132
        for(i=255;i>=0;i--,ptr-=3)
133
        {
134
                j = (ptr[0]>>3)*FASTPALGRIDSIZ*FASTPALGRIDSIZ+(ptr[1]>>3)*FASTPALGRIDSIZ+(ptr[2]>>3)+FASTPALGRIDSIZ*FASTPALGRIDSIZ+FASTPALGRIDSIZ+1;
135
                if (colhere[j>>3]&(1<<(j&7))) colnext[i] = colhead[j]; else colnext[i] = -1;
136
                colhead[j] = i;
137
                colhere[j>>3] |= (1<<(j&7));
138
        }
139
 
140
        i = 0;
141
        for(x=-FASTPALGRIDSIZ*FASTPALGRIDSIZ;x<=FASTPALGRIDSIZ*FASTPALGRIDSIZ;x+=FASTPALGRIDSIZ*FASTPALGRIDSIZ)
142
                for(y=-FASTPALGRIDSIZ;y<=FASTPALGRIDSIZ;y+=FASTPALGRIDSIZ)
143
                        for(z=-1;z<=1;z++)
144
                                colscan[i++] = x+y+z;
145
        i = colscan[13]; colscan[13] = colscan[26]; colscan[26] = i;
146
}
147
 
148
int main(int argc, char **argv)
149
{
150
        char col, ch;
151
        short orignumpalookups;
152
        int fil, i, j, rscale, gscale, bscale;
153
        char buf[65536];
154
 
155
        ch = 13;
156
        if (argc>1) {
157
                if (argv[1][0] == '-') {
158
                        if (argv[1][1] == 't') { ch = 32; puts("Updating translucency table ONLY"); }
159
                        argc--;
160
                        argv++;
161
                }
162
        }
163
 
164
        if ((argc != 3) && (argc != 6))
165
        {
166
                printf("TRANSPAL [-t] [numshades][trans#(0-inv,256-opa)][r][g][b]     by Kenneth Silverman\n");
167
                printf("   Ex #1: transpal 32 170 30 59 11      (I use these values in my BUILD demo)\n");
168
                printf("                           The RGB scales are optional\n");
169
                printf("   Ex #2: transpal 64 160\n\n");
170
                printf("Once tables are generated, the optional -t switch determines what to save:\n");
171
                printf("   Exclude -t to update both the shade table and transluscent table\n");
172
                printf("   Include -t to update the transluscent table ONLY\n");
173
                exit(0);
174
        }
175
 
176
        strcpy(palettefilename,"palette.dat");
177
        numpalookups = atol(argv[1]);
178
        transratio = atol(argv[2]);
179
 
180
        if (argc == 6)
181
        {
182
                rscale = atol(argv[3]);
183
                gscale = atol(argv[4]);
184
                bscale = atol(argv[5]);
185
        }
186
        else
187
        {
188
                rscale = 30;
189
                gscale = 59;
190
                bscale = 11;
191
        }
192
 
193
        if ((numpalookups < 1) || (numpalookups > 256))
194
                { printf("Invalid number of shades\n"); exit(0); }
195
        if ((transratio < 0) || (transratio > 256))
196
                { printf("Invalid transluscent ratio\n"); exit(0); }
197
 
198
        if ((fil = Bopen(palettefilename,BO_BINARY|BO_RDONLY,BS_IREAD)) == -1)
199
        {
200
                printf("%s not found",palettefilename);
201
                return(0);
202
        }
203
        Bread(fil,palette,768);
204
        Bread(fil,&orignumpalookups,2); orignumpalookups = B_LITTLE16(orignumpalookups);
205
        orignumpalookups = min(max(orignumpalookups,1),256);
206
        Bread(fil,origpalookup,(int)orignumpalookups<<8);
207
        Bclose(fil);
208
 
209
        clearbuf(buf,65536>>2,0L);
210
 
211
        initfastcolorlookup(rscale,gscale,bscale);
212
        clearbuf(closestcol,262144>>2,0xffffffff);
213
 
214
        for(i=0;i<numpalookups;i++)
215
                for(j=0;j<256;j++)
216
                {
217
                        col = getpalookup((char)i,(char)j);
218
                        palookup[(i<<8)+j] = col;
219
 
220
                        drawpixel(((((i<<1)+0)*320+(j+8))>>2)+buf,(int)col);
221
                        drawpixel(((((i<<1)+1)*320+(j+8))>>2)+buf,(int)col);
222
                }
223
 
224
        for(i=0;i<256;i++)
225
                for(j=0;j<6;j++)
226
                {
227
                        drawpixel((((j+132+0)*320+(i+8))>>2)+buf,i);
228
 
229
                        drawpixel((((i+132+8)*320+(j+0))>>2)+buf,i);
230
                }
231
 
232
        for(i=0;i<256;i++)
233
                for(j=0;j<256;j++)
234
                {
235
                        col = gettrans((char)i,(char)j,transratio);
236
                        transluc[(i<<8)+j] = col;
237
 
238
                        drawpixel((((j+132+8)*320+(i+8))>>2)+buf,(int)col);
239
                }
240
 
241
        if (ch == 13)
242
        {
243
                short s;
244
                if ((fil = Bopen(palettefilename,BO_BINARY|BO_TRUNC|BO_CREAT|BO_WRONLY,BS_IREAD|BS_IWRITE)) == -1)
245
                        { printf("Couldn't save file %s",palettefilename); return(0); }
246
                Bwrite(fil,palette,768);
247
                s = B_LITTLE16(numpalookups); Bwrite(fil,&s,2);
248
                Bwrite(fil,palookup,numpalookups<<8);
249
                Bwrite(fil,transluc,65536);
250
                Bclose(fil);
251
                printf("Shade table AND transluscent table updated\n");
252
        }
253
        else if (ch == 32)
254
        {
255
                short s;
256
                if ((fil = Bopen(palettefilename,BO_BINARY|BO_TRUNC|BO_CREAT|BO_WRONLY,BS_IREAD|BS_IWRITE)) == -1)
257
                        { printf("Couldn't save file %s",palettefilename); return(0); }
258
                Bwrite(fil,palette,768);
259
                s = B_LITTLE16(orignumpalookups); Bwrite(fil,&s,2);
260
                Bwrite(fil,origpalookup,(int)orignumpalookups<<8);
261
                Bwrite(fil,transluc,65536);
262
                Bclose(fil);
263
                printf("Transluscent table updated\n");
264
        }
265
        else
266
                printf("Palette file wasn't touched\n");
267
 
268
        return 0;
269
}
270