Subversion Repositories eduke32

Rev

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

Rev Author Line No. Line
5789 terminx 1
#include "compat.h"
2
#include "build.h"
5872 hendricks2 3
#include "engine_priv.h"
5862 hendricks2 4
#include "baselayer.h"
5789 terminx 5
#include "colmatch.h"
6
#include "cache1d.h"
7
#include "palette.h"
8
#include "a.h"
9
#include "xxhash.h"
10
 
6061 hendricks2 11
uint8_t *basepaltable[MAXBASEPALS] = { palette };
5789 terminx 12
uint8_t basepalreset=1;
13
uint8_t curbasepal;
14
int32_t globalblend;
15
 
16
uint32_t g_lastpalettesum = 0;
17
palette_t curpalette[256];                      // the current palette, unadjusted for brightness or tint
18
palette_t curpalettefaded[256];         // the current palette, adjusted for brightness and tint (ie. what gets sent to the card)
6061 hendricks2 19
palette_t palfadergb = { 0, 0, 0, 0 };
5789 terminx 20
char palfadedelta = 0;
21
uint8_t blackcol;
22
 
23
#if defined(USE_OPENGL)
24
palette_t palookupfog[MAXPALOOKUPS];
25
#endif
26
 
27
// For every pal number, whether tsprite pal should not be taken over from
28
// floor pal.
29
// NOTE: g_noFloorPal[0] is irrelevant as it's never checked.
30
int8_t g_noFloorPal[MAXPALOOKUPS];
31
 
32
int32_t curbrightness = 0, gammabrightness = 0;
33
 
34
static void setpalettefade_calc(uint8_t offset);
35
 
36
void fade_screen_black(int32_t moreopaquep)
37
{
38
#ifdef USE_OPENGL
39
    if (getrendermode() >= REND_POLYMOST)
40
        fullscreen_tint_gl(0, 0, 0, moreopaquep ? 168 : 84);
41
    else
42
#endif
43
    {
44
        Bassert(!offscreenrendering);
45
 
46
        begindrawing();
47
        {
48
            char *const p = (char *) frameplace;
49
            const char *const trans = getblendtab(0);
50
            const int32_t shiftamnt = ((!!moreopaquep)*8);
51
            const int32_t dimprod = xdim*ydim;
52
            int32_t i = 0;
53
 
54
#ifdef CLASSIC_SLICE_BY_4
55
            for (; i<dimprod-4; i+=4)
56
            {
57
                p[i] = trans[p[i]<<shiftamnt];
58
                p[i+1] = trans[p[i+1]<<shiftamnt];
59
                p[i+2] = trans[p[i+2]<<shiftamnt];
60
                p[i+3] = trans[p[i+3]<<shiftamnt];
61
            }
62
#endif
63
 
64
            for (; i<dimprod; i++)
65
                p[i] = trans[p[i]<<shiftamnt];
66
        }
67
        enddrawing();
68
    }
69
}
70
 
71
void setup_blend(int32_t blend, int32_t doreverse)
72
{
73
    if (blendtable[blend] == NULL)
74
        blend = 0;
75
 
76
    if (globalblend != blend)
77
    {
78
        globalblend = blend;
79
        fixtransluscence(FP_OFF(getblendtab(blend)));
80
    }
81
 
82
    if (doreverse)
83
        settransreverse();
84
    else
85
        settransnormal();
86
}
87
 
88
static void alloc_palookup(int32_t pal)
89
{
90
    // The asm functions vlineasm1, mvlineasm1 (maybe others?) access the next
91
    // palookup[...] shade entry for tilesizy==512 tiles.
92
    // See DEBUG_TILESIZY_512 and the comment in a.nasm: vlineasm1.
6438 terminx 93
    palookup[pal] = (char *) Xaligned_alloc(16, (numshades + 1) * 256);
94
    memset(palookup[pal], 0, (numshades + 1) * 256);
5789 terminx 95
}
96
 
97
static void maybe_alloc_palookup(int32_t palnum);
98
 
99
//
100
// loadpalette (internal)
101
//
102
void loadpalette(void)
103
{
104
    initfastcolorlookup_scale(30, 59, 11);
105
    initfastcolorlookup_gridvectors();
106
 
5888 hendricks2 107
#ifdef USE_OPENGL
108
    for (size_t x = 0; x < MAXBLENDTABS; ++x)
109
        glblend[x] = defaultglblend;
110
#endif
111
 
5789 terminx 112
    int32_t fil;
113
    if ((fil = kopen4load("palette.dat", 0)) == -1)
114
        return;
115
 
116
 
117
    // PALETTE_MAIN
118
 
119
    if (kread_and_test(fil, palette, 768))
120
        return kclose(fil);
121
 
5829 terminx 122
    for (bssize_t k = 0; k < 768; k++)
5789 terminx 123
        palette[k] <<= 2;
124
 
125
    initfastcolorlookup_palette(palette);
126
 
127
    paletteloaded |= PALETTE_MAIN;
128
 
129
 
130
    // PALETTE_SHADES
131
 
132
    if (kread_and_test(fil, &numshades, 2))
133
        return kclose(fil);
134
    numshades = B_LITTLE16(numshades);
135
 
136
    if (numshades <= 1)
137
    {
138
        initprintf("Warning: Invalid number of shades in \"palette.dat\"!\n");
139
        numshades = 0;
140
        return kclose(fil);
141
    }
142
 
143
    // Auto-detect LameDuke. Its PALETTE.DAT doesn't have a 'numshades' 16-bit
144
    // int after the base palette, but starts directly with the shade tables.
145
    // Thus, the first two bytes will be 00 01, which is 256 if read as
146
    // little-endian int16_t.
147
    int32_t lamedukep = 0;
148
    if (numshades >= 256)
149
    {
150
        static char const * const seekfail = "Warning: klseek() failed in loadpalette()!\n";
151
 
152
        uint16_t temp;
153
        if (kread_and_test(fil, &temp, 2))
154
            return kclose(fil);
155
        temp = B_LITTLE16(temp);
156
        if (temp == 770 || numshades > 256) // 02 03
157
        {
158
            if (klseek(fil, -4, BSEEK_CUR) < 0)
159
            {
160
                initputs(seekfail);
161
                return kclose(fil);
162
            }
163
 
164
            numshades = 32;
165
            lamedukep = 1;
166
        }
167
        else
168
        {
169
            if (klseek(fil, -2, BSEEK_CUR) < 0)
170
            {
171
                initputs(seekfail);
172
                return kclose(fil);
173
            }
174
        }
175
    }
176
 
177
    // Read base shade table (palookup 0).
178
    maybe_alloc_palookup(0);
179
    if (kread_and_test(fil, palookup[0], numshades<<8))
180
        return kclose(fil);
181
 
182
    paletteloaded |= PALETTE_SHADE;
183
 
184
 
185
    // PALETTE_TRANSLUC
186
 
187
    char * const transluc = blendtable[0] = (char *) Xcalloc(256, 256);
188
 
189
    // Read translucency (blending) table.
190
    if (lamedukep)
191
    {
5829 terminx 192
        for (bssize_t i=0; i<255; i++)
5789 terminx 193
        {
194
            // NOTE: LameDuke's table doesn't have the last row or column (i==255).
195
 
196
            // Read the entries above and on the diagonal, if the table is
197
            // thought as being row-major.
198
            if (kread_and_test(fil, &transluc[256*i + i], 256-i-1))
199
                return kclose(fil);
200
 
201
            // Duplicate the entries below the diagonal.
5829 terminx 202
            for (bssize_t j=0; j<i; j++)
5789 terminx 203
                transluc[256*i + j] = transluc[256*j + i];
204
        }
205
    }
206
    else
207
    {
208
        if (kread_and_test(fil, transluc, 65536))
209
            return kclose(fil);
210
    }
211
 
212
    paletteloaded |= PALETTE_TRANSLUC;
213
 
214
 
215
    // additional blending tables
216
 
217
    uint8_t magic[12];
218
    if (!kread_and_test(fil, magic, sizeof(magic)) && !Bmemcmp(magic, "MoreBlendTab", sizeof(magic)))
219
    {
220
        uint8_t addblendtabs;
221
        if (kread_and_test(fil, &addblendtabs, 1))
222
        {
223
            initprintf("Warning: failed reading additional blending table count\n");
224
            return kclose(fil);
225
        }
226
 
227
        uint8_t blendnum;
228
        char *tab = (char *) Xmalloc(256*256);
5829 terminx 229
        for (bssize_t i=0; i<addblendtabs; i++)
5789 terminx 230
        {
231
            if (kread_and_test(fil, &blendnum, 1))
232
            {
233
                initprintf("Warning: failed reading additional blending table index\n");
234
                Bfree(tab);
235
                return kclose(fil);
236
            }
237
 
238
            if (getblendtab(blendnum) != NULL)
239
                initprintf("Warning: duplicate blending table index %3d encountered\n", blendnum);
240
 
241
            if (kread_and_test(fil, tab, 256*256))
242
            {
243
                initprintf("Warning: failed reading additional blending table\n");
244
                Bfree(tab);
245
                return kclose(fil);
246
            }
247
 
248
            setblendtab(blendnum, tab);
249
        }
250
        Bfree(tab);
251
 
252
        // Read log2 of count of alpha blending tables.
253
        uint8_t lognumalphatabs;
254
        if (!kread_and_test(fil, &lognumalphatabs, 1))
255
        {
256
            if (!(lognumalphatabs >= 1 && lognumalphatabs <= 7))
257
                initprintf("invalid lognumalphatabs value, must be in [1 .. 7]\n");
258
            else
259
                numalphatabs = 1<<lognumalphatabs;
260
        }
261
    }
262
 
263
    kclose(fil);
264
}
265
 
266
uint32_t PaletteIndexFullbrights[8];
267
 
5952 hendricks2 268
void E_PostLoadPalette(void)
5789 terminx 269
{
270
    globalpal = 0;
5872 hendricks2 271
 
5789 terminx 272
    globalpalwritten = palookup[0];
273
    setpalookupaddress(globalpalwritten);
274
 
275
    fixtransluscence(FP_OFF(blendtable[0]));
276
 
6513 hendricks2 277
    char const * const palookup0 = palookup[0];
278
 
5789 terminx 279
#ifdef DEBUG_TILESIZY_512
280
    // Bump shade 1 by 16.
5829 terminx 281
    for (bssize_t i=256; i<512; i++)
6513 hendricks2 282
        palookup0[i] = palookup0[i+(16<<8)];
5789 terminx 283
#endif
284
 
6513 hendricks2 285
    blackcol = getclosestcol(0, 0, 0);
286
    whitecol = getclosestcol(255, 255, 255);
5789 terminx 287
    redcol = getclosestcol(255, 0, 0);
288
 
6461 terminx 289
    for (size_t i = 0; i<16; i++)
290
    {
291
        palette_t *edcol = (palette_t *) &vgapal16[4*i];
292
        editorcolors[i] = getclosestcol_lim(edcol->b, edcol->g, edcol->r, 239);
293
    }
294
 
5789 terminx 295
    // Bmemset(PaletteIndexFullbrights, 0, sizeof(PaletteIndexFullbrights));
5829 terminx 296
    for (bssize_t c = 0; c < 255; ++c) // skipping transparent color
5789 terminx 297
    {
6513 hendricks2 298
        uint8_t const index = palookup0[c];
299
        rgb24_t const & color = *(rgb24_t *)&palette[index*3];
5789 terminx 300
 
6513 hendricks2 301
        // don't consider #000000 fullbright
302
        if (EDUKE32_PREDICT_FALSE(color.r == 0 && color.g == 0 && color.b == 0))
303
            continue;
5789 terminx 304
 
6513 hendricks2 305
        for (size_t s = c + 256, s_end = 256*numshades; s < s_end; s += 256)
306
            if (EDUKE32_PREDICT_FALSE(palookup0[s] != index))
5789 terminx 307
                goto PostLoad_NotFullbright;
308
 
309
        SetPaletteIndexFullbright(c);
310
 
6513 hendricks2 311
        PostLoad_NotFullbright: ;
5789 terminx 312
    }
313
}
314
 
315
void E_ReplaceTransparentColorWithBlack(void)
316
{
5829 terminx 317
    for (bssize_t i=0; i<MAXPALOOKUPS; i++)
5789 terminx 318
    {
319
        char * const thispalookup = palookup[i];
320
        if (thispalookup == NULL)
321
            continue;
322
 
5829 terminx 323
        for (bssize_t j=0; j<numshades; j++)
5789 terminx 324
        {
325
            thispalookup[(j<<8) + 255] = 255;
326
        }
327
    }
328
 
329
    // fix up translucency table so that transluc(255,x)
330
    // and transluc(x,255) is black instead of purple.
5829 terminx 331
    for (bssize_t i=0; i<MAXBLENDTABS; i++)
5789 terminx 332
    {
333
        char * const transluc = blendtable[i];
334
        if (transluc == NULL)
335
            continue;
336
 
5829 terminx 337
        for (bssize_t j=0; j<255; j++)
5789 terminx 338
        {
339
            transluc[(255<<8) + j] = transluc[(blackcol<<8) + j];
340
            transluc[255 + (j<<8)] = transluc[blackcol + (j<<8)];
341
        }
342
        transluc[(255<<8) + 255] = transluc[(blackcol<<8) + blackcol];
343
    }
344
}
345
 
346
// Load LOOKUP.DAT, which contains lookup tables and additional base palettes.
347
//
348
// <fp>: kopen4load file handle
349
//
350
// Returns:
351
//  - on success, 0
352
//  - on error, -1 (didn't read enough data)
353
//  - -2: error, we already wrote an error message ourselves
354
int32_t loadlookups(int32_t fp)
355
{
356
    uint8_t numlookups;
357
    char remapbuf[256];
358
 
359
    if (kread_and_test(fp, &numlookups, 1))
360
        return -1;
361
 
5829 terminx 362
    for (bssize_t j=0; j<numlookups; j++)
5789 terminx 363
    {
364
        uint8_t palnum;
365
 
366
        if (kread_and_test(fp, &palnum, 1))
367
            return -1;
368
 
369
        if (palnum >= 256-RESERVEDPALS)
370
        {
371
            initprintf("ERROR: attempt to load lookup at reserved pal %d\n", palnum);
372
            return -2;
373
        }
374
 
375
        if (kread_and_test(fp, remapbuf, 256))
376
            return -1;
377
 
378
        makepalookup(palnum, remapbuf, 0, 0, 0, 0);
379
    }
380
 
381
    return 0;
382
}
383
 
384
void generatefogpals(void)
385
{
386
    // Find a gap of four consecutive unused pal numbers to generate fog shade
387
    // tables.
5829 terminx 388
    for (bssize_t j=1; j<=255-3; j++)
5789 terminx 389
        if (!palookup[j] && !palookup[j+1] && !palookup[j+2] && !palookup[j+3])
390
        {
391
            makepalookup(j, NULL, 60, 60, 60, 1);
392
            makepalookup(j+1, NULL, 60, 0, 0, 1);
393
            makepalookup(j+2, NULL, 0, 60, 0, 1);
394
            makepalookup(j+3, NULL, 0, 0, 60, 1);
395
 
396
            break;
397
        }
398
}
399
 
400
void fillemptylookups(void)
401
{
402
    // Alias remaining unused pal numbers to the base shade table.
5829 terminx 403
    for (bssize_t j=1; j<MAXPALOOKUPS; j++)
5789 terminx 404
    {
405
        // If an existing lookup is identical to #0, free it.
406
        if (palookup[j] && palookup[j] != palookup[0] && !Bmemcmp(palookup[0], palookup[j], 256*numshades))
407
            removepalookup(j);
408
 
409
        if (!palookup[j])
410
            makepalookup(j, NULL, 0, 0, 0, 1);
411
    }
412
}
413
 
414
static int32_t palookup_isdefault(int32_t palnum)  // KEEPINSYNC engine.lua
415
{
416
    return (palookup[palnum] == NULL || (palnum!=0 && palookup[palnum] == palookup[0]));
417
}
418
 
419
static void maybe_alloc_palookup(int32_t palnum)
420
{
421
    if (palookup_isdefault(palnum))
422
    {
423
        alloc_palookup(palnum);
424
        if (palookup[palnum] == NULL)
425
            Bexit(1);
426
    }
427
}
428
 
429
void setblendtab(int32_t blend, const char *tab)
430
{
431
    if (blendtable[blend] == NULL)
432
        blendtable[blend] = (char *) Xmalloc(256*256);
433
 
434
    Bmemcpy(blendtable[blend], tab, 256*256);
435
}
436
void removeblendtab(int32_t const blend)
437
{
438
    DO_FREE_AND_NULL(blendtable[blend]);
439
}
440
 
441
#ifdef LUNATIC
442
const char *(getblendtab) (int32_t blend)
443
{
444
    return blendtable[blend];
445
}
446
#endif
447
 
5888 hendricks2 448
#ifdef USE_OPENGL
449
glblend_t const nullglblend =
450
{
451
    {
452
        { 1.f, BLENDFACTOR_ONE, BLENDFACTOR_ZERO, 0 },
453
        { 1.f, BLENDFACTOR_ONE, BLENDFACTOR_ZERO, 0 },
454
    },
455
};
456
glblend_t const defaultglblend =
457
{
458
    {
459
        { 2.f/3.f, BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 0 },
460
        { 1.f/3.f, BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 0 },
461
    },
462
};
463
 
464
glblend_t glblend[MAXBLENDTABS];
465
 
466
void handle_blend(uint8_t enable, uint8_t blend, uint8_t def)
467
{
468
    static GLenum const blendFuncTokens[NUMBLENDFACTORS] =
469
    {
470
        GL_ZERO,
471
        GL_ONE,
472
        GL_SRC_COLOR,
473
        GL_ONE_MINUS_SRC_COLOR,
474
        GL_SRC_ALPHA,
475
        GL_ONE_MINUS_SRC_ALPHA,
476
        GL_DST_ALPHA,
477
        GL_ONE_MINUS_DST_ALPHA,
478
        GL_DST_COLOR,
479
        GL_ONE_MINUS_DST_COLOR,
480
    };
481
 
482
    if (!enable)
483
    {
484
        bglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
485
        return;
486
    }
487
 
488
    glblenddef_t const * const glbdef = glblend[blend].def + def;
489
    bglBlendFunc(blendFuncTokens[glbdef->src], blendFuncTokens[glbdef->dst]);
490
}
491
#endif
492
 
5789 terminx 493
int32_t setpalookup(int32_t palnum, const uint8_t *shtab)
494
{
495
    if (numshades != 32)
496
        return -1;
497
 
498
    if (shtab != NULL)
499
    {
500
        maybe_alloc_palookup(palnum);
501
        Bmemcpy(palookup[palnum], shtab, 256*numshades);
502
    }
503
 
504
    return 0;
505
}
506
void removepalookup(int32_t const palnum)
507
{
508
    if (palnum == 0 && palookup[palnum] != NULL)
509
    {
5829 terminx 510
        for (bssize_t i = 1; i < MAXPALOOKUPS; i++)
5789 terminx 511
            if (palookup[i] == palookup[palnum])
512
                palookup[i] = NULL;
513
 
6438 terminx 514
        ALIGNED_FREE_AND_NULL(palookup[palnum]);
5789 terminx 515
    }
516
    else if (palookup[palnum] == palookup[0])
517
        palookup[palnum] = NULL;
518
    else
6438 terminx 519
        ALIGNED_FREE_AND_NULL(palookup[palnum]);
5789 terminx 520
}
521
 
522
//
523
// makepalookup
524
//
525
void makepalookup(int32_t palnum, const char *remapbuf, uint8_t r, uint8_t g, uint8_t b, char noFloorPal)
526
{
527
    int32_t i, j;
528
 
6061 hendricks2 529
    static char idmap[256] = { 1 };
5789 terminx 530
 
531
    if (paletteloaded == 0)
532
        return;
533
 
534
    // NOTE: palnum==0 is allowed
535
    if ((unsigned) palnum >= MAXPALOOKUPS)
536
        return;
537
 
538
    g_noFloorPal[palnum] = noFloorPal;
539
 
540
    if (remapbuf==NULL)
541
    {
542
        if ((r|g|b) == 0)
543
        {
544
            palookup[palnum] = palookup[0];  // Alias to base shade table!
545
            return;
546
        }
547
 
548
        if (idmap[0]==1)  // init identity map
549
            for (i=0; i<256; i++)
550
                idmap[i] = i;
551
 
552
        remapbuf = idmap;
553
    }
554
 
555
    maybe_alloc_palookup(palnum);
556
 
557
    if ((r|g|b) == 0)
558
    {
559
        // "black fog"/visibility case -- only remap color indices
560
 
561
        for (j=0; j<numshades; j++)
562
            for (i=0; i<256; i++)
563
            {
564
                const char *src = palookup[0];
565
                palookup[palnum][256*j + i] = src[256*j + remapbuf[i]];
566
            }
567
    }
568
    else
569
    {
570
        // colored fog case
571
 
572
        char *ptr2 = palookup[palnum];
573
 
574
        for (i=0; i<numshades; i++)
575
        {
576
            int32_t palscale = divscale16(i, numshades-1);
577
 
578
            for (j=0; j<256; j++)
579
            {
580
                const char *ptr = (const char *) &palette[remapbuf[j]*3];
581
                *ptr2++ = getclosestcol(ptr[0] + mulscale16(r-ptr[0], palscale),
582
                    ptr[1] + mulscale16(g-ptr[1], palscale),
583
                    ptr[2] + mulscale16(b-ptr[2], palscale));
584
            }
585
        }
586
    }
587
 
588
#if defined(USE_OPENGL)
589
    palookupfog[palnum].r = r;
590
    palookupfog[palnum].g = g;
591
    palookupfog[palnum].b = b;
592
#endif
593
}
594
 
595
//
596
// setbasepal
597
//
598
void setbasepal(int32_t id, uint8_t const * const table)
599
{
600
    if (basepaltable[id] == NULL)
601
        basepaltable[id] = (uint8_t *) Xmalloc(768);
602
 
603
    Bmemcpy(basepaltable[id], table, 768);
604
}
605
void removebasepal(int32_t const id)
606
{
607
    if (id == 0)
608
        Bmemset(basepaltable[id], 0, 768);
609
    else
610
        DO_FREE_AND_NULL(basepaltable[id]);
611
}
612
 
613
//
614
// setbrightness
615
//
616
// flags:
617
//  1: don't setpalette(),  DON'T USE THIS FLAG!
618
//  2: don't gltexinvalidateall()
619
//  4: don't calc curbrightness from dabrightness,  DON'T USE THIS FLAG!
620
//  8: don't gltexinvalidate8()
621
// 16: don't reset palfade*
622
void setbrightness(char dabrightness, uint8_t dapalid, uint8_t flags)
623
{
5884 terminx 624
    int32_t i, j;
5789 terminx 625
    const uint8_t *dapal;
626
 
627
#ifdef USE_OPENGL
628
    int32_t paldidchange;
629
#endif
630
    int32_t palsumdidchange;
631
    //    uint32_t lastbright = curbrightness;
632
 
633
    Bassert((flags&4)==0);
634
 
635
    if (/*(unsigned)dapalid >= MAXBASEPALS ||*/ basepaltable[dapalid] == NULL)
636
        dapalid = 0;
637
#ifdef USE_OPENGL
638
    paldidchange = (curbasepal != dapalid || basepalreset);
639
#endif
640
    curbasepal = dapalid;
641
    basepalreset = 0;
642
 
643
    dapal = basepaltable[curbasepal];
644
 
645
    if (!(flags&4))
646
    {
647
        curbrightness = clamp(dabrightness, 0, 15);
648
        //        if (lastbright != (unsigned)curbrightness)
649
        //            vid_gamma = 1.0 + ((float)curbrightness / 10.0);
650
    }
651
 
5884 terminx 652
    setgamma();
653
    j = !gammabrightness ? curbrightness : 0;
5789 terminx 654
 
655
    for (i=0; i<256; i++)
656
    {
657
        // save palette without any brightness adjustment
658
        curpalette[i].r = dapal[i*3+0];
659
        curpalette[i].g = dapal[i*3+1];
660
        curpalette[i].b = dapal[i*3+2];
661
        curpalette[i].f = 0;
662
 
663
        // brightness adjust the palette
664
        curpalettefaded[i].b = britable[j][curpalette[i].b];
665
        curpalettefaded[i].g = britable[j][curpalette[i].g];
666
        curpalettefaded[i].r = britable[j][curpalette[i].r];
667
        curpalettefaded[i].f = 0;
668
    }
669
 
670
    if ((flags&16) && palfadedelta)  // keep the fade
671
        setpalettefade_calc(palfadedelta>>2);
672
 
673
    {
674
        static uint32_t lastpalettesum=0;
675
        uint32_t newpalettesum = XXH32((uint8_t *) curpalettefaded, sizeof(curpalettefaded), sizeof(curpalettefaded));
676
 
677
        palsumdidchange = (newpalettesum != lastpalettesum);
678
 
679
        if (palsumdidchange || newpalettesum != g_lastpalettesum)
680
        {
681
            //            if ((flags&1) == 0)
682
            setpalette(0, 256);
683
        }
684
 
685
        g_lastpalettesum = lastpalettesum = newpalettesum;
686
    }
687
 
688
#ifdef USE_OPENGL
689
    if (getrendermode() >= REND_POLYMOST)
690
    {
691
        // Only reset the textures if the corresponding preserve flags are clear and
692
        // either (a) the new palette is different to the last, or (b) the brightness
693
        // changed and we couldn't set it using hardware gamma.
694
 
695
        // XXX: no-HW-gamma OpenGL platforms will exhibit bad performance with
696
        // simultaneous basepal and tint changes?
5884 terminx 697
        const int32_t doinvalidate = (paldidchange || (palsumdidchange && !gammabrightness));
5789 terminx 698
 
699
        if (!(flags&2) && doinvalidate)
700
            gltexinvalidatetype(INVALIDATE_ALL);
701
        if (!(flags&8) && doinvalidate)
702
            gltexinvalidatetype(INVALIDATE_ART);
703
#ifdef POLYMER
704
        if ((getrendermode() == REND_POLYMER) && doinvalidate)
705
            polymer_texinvalidate();
706
#endif
707
    }
708
#endif
709
 
710
    if ((flags&16)==0)
711
    {
712
        palfadergb.r = palfadergb.g = palfadergb.b = 0;
713
        palfadedelta = 0;
714
    }
715
}
716
 
5804 terminx 717
palette_t getpal(int32_t col)
5789 terminx 718
{
719
    if (!gammabrightness)
720
    {
5884 terminx 721
        palette_t const p = { britable[curbrightness][curpalette[col].r], britable[curbrightness][curpalette[col].g],
722
                              britable[curbrightness][curpalette[col].b], 0 };
5789 terminx 723
        return p;
724
    }
725
 
726
    return curpalette[col];
727
}
728
 
729
static void setpalettefade_calc(uint8_t offset)
730
{
731
    int32_t i;
732
    palette_t p;
733
 
734
    for (i=0; i<256; i++)
735
    {
736
        p = getpal(i);
737
 
738
        curpalettefaded[i].b =
739
            p.b + (((palfadergb.b - p.b) * offset) >> 8);
740
        curpalettefaded[i].g =
741
            p.g + (((palfadergb.g - p.g) * offset) >> 8);
742
        curpalettefaded[i].r =
743
            p.r + (((palfadergb.r - p.r) * offset) >> 8);
744
        curpalettefaded[i].f = 0;
745
    }
746
}
747
 
748
//#define DEBUG_PALETTEFADE
749
 
750
//
751
// setpalettefade
752
//
753
void setpalettefade(uint8_t r, uint8_t g, uint8_t b, uint8_t offset)
754
{
755
    palfadergb.r = r;
756
    palfadergb.g = g;
757
    palfadergb.b = b;
758
#ifdef DEBUG_PALETTEFADE
759
    if (offset)
760
        offset = max(offset, 128);
761
#endif
762
    palfadedelta = offset;
763
 
764
    setpalettefade_calc(offset);
765
 
766
    {
767
        static uint32_t lastpalettesum=0;
768
        uint32_t newpalettesum = XXH32((uint8_t *) curpalettefaded, sizeof(curpalettefaded), sizeof(curpalettefaded));
769
 
770
        if (newpalettesum != lastpalettesum || newpalettesum != g_lastpalettesum)
771
            setpalette(0, 256);
772
 
773
        g_lastpalettesum = lastpalettesum = newpalettesum;
774
    }
775
}