1 /*
2 * High-colour textures support for Polymost
3 * by Jonathon Fowler
4 * See the included license file "BUILDLIC.TXT" for license info.
5 */
6
7 #include "build.h"
8
9 #if USE_POLYMOST && USE_OPENGL
10
11 #include "kplib.h"
12 #include "hightile_priv.h"
13
14 palette_t hictinting[MAXPALOOKUPS];
15
16 hicreplctyp *hicreplc[MAXTILES];
17 int hicfirstinit = 0;
18
19 /**
20 * Find a substitute definition which satisfies the given parameters.
21 * This will try for a perfect match with the requested palette, or if
22 * none is found, try and find a palette 0 equivalent.
23 *
24 * @param picnum tile number
25 * @param palnum palette index
26 * @param skybox 'true' to find a substitute that defines a skybox
27 * @return the substitute header, or null
28 */
hicfindsubst(int picnum,int palnum,int skybox)29 hicreplctyp * hicfindsubst(int picnum, int palnum, int skybox)
30 {
31 hicreplctyp *hr;
32
33 if (!hicfirstinit) return NULL;
34 if ((unsigned int)picnum >= (unsigned int)MAXTILES) return NULL;
35
36 do {
37 for (hr = hicreplc[picnum]; hr; hr = hr->next) {
38 if (hr->palnum == palnum) {
39 if (skybox) {
40 if (hr->skybox && !hr->skybox->ignore) return hr;
41 } else {
42 if (!hr->ignore) return hr;
43 }
44 }
45 }
46
47 if (palnum == 0) break;
48 palnum = 0;
49 } while (1);
50
51 return NULL; // no replacement found
52 }
53
54
55 /**
56 * Initialise the high-colour stuff to a default state
57 */
hicinit(void)58 void hicinit(void)
59 {
60 int i,j;
61 hicreplctyp *hr, *next;
62
63 for (i=0;i<MAXPALOOKUPS;i++) { // all tints should be 100%
64 hictinting[i].r = hictinting[i].g = hictinting[i].b = 0xff;
65 hictinting[i].f = 0;
66 }
67
68 if (hicfirstinit) {
69 for (i=MAXTILES-1;i>=0;i--) {
70 for (hr=hicreplc[i]; hr; ) {
71 next = hr->next;
72
73 if (hr->skybox) {
74 for (j=5;j>=0;j--) {
75 if (hr->skybox->face[j]) {
76 free(hr->skybox->face[j]);
77 }
78 }
79 free(hr->skybox);
80 }
81 if (hr->filename) free(hr->filename);
82 free(hr);
83
84 hr = next;
85 }
86 }
87 }
88 memset(hicreplc,0,sizeof(hicreplc));
89
90 hicfirstinit = 1;
91 }
92
93
94 //
95 // hicsetpalettetint(pal,r,g,b,effect)
96 // The tinting values represent a mechanism for emulating the effect of global sector
97 // palette shifts on true-colour textures and only true-colour textures.
98 // effect bitset: 1 = greyscale, 2 = invert
99 //
hicsetpalettetint(int palnum,unsigned char r,unsigned char g,unsigned char b,unsigned char effect)100 void hicsetpalettetint(int palnum, unsigned char r, unsigned char g, unsigned char b, unsigned char effect)
101 {
102 if ((unsigned int)palnum >= (unsigned int)MAXPALOOKUPS) return;
103 if (!hicfirstinit) hicinit();
104
105 hictinting[palnum].r = r;
106 hictinting[palnum].g = g;
107 hictinting[palnum].b = b;
108 hictinting[palnum].f = effect & HICEFFECTMASK;
109 }
110
111
112 //
113 // hicsetsubsttex(picnum,pal,filen,alphacut)
114 // Specifies a replacement graphic file for an ART tile.
115 //
hicsetsubsttex(int picnum,int palnum,char * filen,float alphacut,unsigned char flags)116 int hicsetsubsttex(int picnum, int palnum, char *filen, float alphacut, unsigned char flags)
117 {
118 hicreplctyp *hr, *hrn;
119
120 if ((unsigned int)picnum >= (unsigned int)MAXTILES) return -1;
121 if ((unsigned int)palnum >= (unsigned int)MAXPALOOKUPS) return -1;
122 if (!hicfirstinit) hicinit();
123
124 for (hr = hicreplc[picnum]; hr; hr = hr->next) {
125 if (hr->palnum == palnum)
126 break;
127 }
128
129 if (!hr) {
130 // no replacement yet defined
131 hrn = (hicreplctyp *)calloc(1,sizeof(hicreplctyp));
132 if (!hrn) return -1;
133 hrn->palnum = palnum;
134 } else hrn = hr;
135
136 // store into hicreplc the details for this replacement
137 if (hrn->filename) free(hrn->filename);
138
139 hrn->filename = strdup(filen);
140 if (!hrn->filename) {
141 if (hrn->skybox) return -1; // don't free the base structure if there's a skybox defined
142 if (hr == NULL) free(hrn); // not yet a link in the chain
143 return -1;
144 }
145 hrn->ignore = 0;
146 hrn->alphacut = min(alphacut,1.0);
147 hrn->flags = flags;
148 if (hr == NULL) {
149 hrn->next = hicreplc[picnum];
150 hicreplc[picnum] = hrn;
151 }
152
153 //printf("Replacement [%d,%d]: %s\n", picnum, palnum, hicreplc[i]->filename);
154
155 return 0;
156 }
157
158
159 //
160 // hicsetskybox(picnum,pal,faces[6])
161 // Specifies a graphic files making up a skybox.
162 //
hicsetskybox(int picnum,int palnum,char * faces[6])163 int hicsetskybox(int picnum, int palnum, char *faces[6])
164 {
165 hicreplctyp *hr, *hrn;
166 int j;
167
168 if ((unsigned int)picnum >= (unsigned int)MAXTILES) return -1;
169 if ((unsigned int)palnum >= (unsigned int)MAXPALOOKUPS) return -1;
170 for (j=5;j>=0;j--) if (!faces[j]) return -1;
171 if (!hicfirstinit) hicinit();
172
173 for (hr = hicreplc[picnum]; hr; hr = hr->next) {
174 if (hr->palnum == palnum)
175 break;
176 }
177
178 if (!hr) {
179 // no replacement yet defined
180 hrn = (hicreplctyp *)calloc(1,sizeof(hicreplctyp));
181 if (!hrn) return -1;
182
183 hrn->palnum = palnum;
184 } else hrn = hr;
185
186 if (!hrn->skybox) {
187 hrn->skybox = (struct hicskybox_t *)calloc(1,sizeof(struct hicskybox_t));
188 if (!hrn->skybox) {
189 if (hr == NULL) free(hrn); // not yet a link in the chain
190 return -1;
191 }
192 } else {
193 for (j=5;j>=0;j--) {
194 if (hrn->skybox->face[j])
195 free(hrn->skybox->face[j]);
196 }
197 }
198
199 // store each face's filename
200 for (j=0;j<6;j++) {
201 hrn->skybox->face[j] = strdup(faces[j]);
202 if (!hrn->skybox->face[j]) {
203 for (--j; j>=0; --j) // free any previous faces
204 free(hrn->skybox->face[j]);
205 free(hrn->skybox);
206 hrn->skybox = NULL;
207 if (hr == NULL) free(hrn);
208 return -1;
209 }
210 }
211 hrn->skybox->ignore = 0;
212 if (hr == NULL) {
213 hrn->next = hicreplc[picnum];
214 hicreplc[picnum] = hrn;
215 }
216
217 return 0;
218 }
219
220
221 //
222 // hicclearsubst(picnum,pal)
223 // Clears a replacement for an ART tile, including skybox faces.
224 //
hicclearsubst(int picnum,int palnum)225 int hicclearsubst(int picnum, int palnum)
226 {
227 hicreplctyp *hr, *hrn = NULL;
228
229 if ((unsigned int)picnum >= (unsigned int)MAXTILES) return -1;
230 if ((unsigned int)palnum >= (unsigned int)MAXPALOOKUPS) return -1;
231 if (!hicfirstinit) return 0;
232
233 for (hr = hicreplc[picnum]; hr; hrn = hr, hr = hr->next) {
234 if (hr->palnum == palnum)
235 break;
236 }
237
238 if (!hr) return 0;
239
240 if (hr->filename) free(hr->filename);
241 if (hr->skybox) {
242 int i;
243 for (i=5;i>=0;i--)
244 if (hr->skybox->face[i])
245 free(hr->skybox->face[i]);
246 free(hr->skybox);
247 }
248
249 if (hrn) hrn->next = hr->next;
250 else hicreplc[picnum] = hr->next;
251 free(hr);
252
253 return 0;
254 }
255
256 #endif //USE_POLYMOST && USE_OPENGL
257