Subversion Repositories eduke32

Rev

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