Subversion Repositories eduke32

Rev

Rev 5884 | Rev 5952 | 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
 
11
uint8_t *basepaltable[MAXBASEPALS] ={ palette };
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)
19
palette_t palfadergb ={ 0,0,0,0 };
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
#if defined ENGINE_USING_A_C || (defined CLASSIC_NONPOW2_YSIZE_WALLS && defined CLASSIC_NONPOW2_YSIZE_SPRITES)
91
    palookup[pal] = (char *) Xmalloc(numshades*256);
92
#else
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.
96
    palookup[pal] = (char *) Xcalloc(numshades+1, 256);
97
#endif
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
 
271
static void E_PostLoadPalette(void)
272
{
273
    globalpal = 0;
5872 hendricks2 274
 
5789 terminx 275
    globalpalwritten = palookup[0];
276
    setpalookupaddress(globalpalwritten);
277
 
278
    fixtransluscence(FP_OFF(blendtable[0]));
279
 
280
#ifdef DEBUG_TILESIZY_512
281
    // Bump shade 1 by 16.
5829 terminx 282
    for (bssize_t i=256; i<512; i++)
5789 terminx 283
        palookup[0][i] = palookup[0][i+(16<<8)];
284
#endif
285
 
286
    // find white and black colors
5829 terminx 287
    for (bssize_t i=0, j, k=0; i<256; i++)
5789 terminx 288
    {
289
        j = palette[i*3] + palette[i*3+1] + palette[i*3+2];
290
        if (j > k) { k = j; whitecol = i; }
291
    }
5829 terminx 292
    for (bssize_t i=0, j, k=768; i<256; i++)
5789 terminx 293
    {
294
        j = palette[i*3] + palette[i*3+1] + palette[i*3+2];
295
        if (j < k) { k = j; blackcol = i; }
296
    }
297
 
298
    redcol = getclosestcol(255, 0, 0);
299
 
300
    // Bmemset(PaletteIndexFullbrights, 0, sizeof(PaletteIndexFullbrights));
5829 terminx 301
    for (bssize_t c = 0; c < 255; ++c) // skipping transparent color
5789 terminx 302
    {
303
        char const * const thispalookup = palookup[0];
304
        char const color = thispalookup[c];
305
 
306
        if (EDUKE32_PREDICT_FALSE(palette[color*3] == 0 &&
307
            palette[color*3+1] == 0 &&
308
            palette[color*3+2] == 0))
309
            continue; // don't consider #000000 fullbright
310
 
5829 terminx 311
        for (bssize_t s = c + 256; s < 256*32; s += 256)
5789 terminx 312
            if (EDUKE32_PREDICT_FALSE(thispalookup[s] != color))
313
                goto PostLoad_NotFullbright;
314
 
315
        SetPaletteIndexFullbright(c);
316
 
317
    PostLoad_NotFullbright:
318
        continue; // should be optimized out
319
    }
320
}
321
 
322
//
323
// E_PostInitTables
324
//
325
 
326
int32_t E_PostInitTables(void)
327
{
328
    if (!(paletteloaded & PALETTE_MAIN))
329
        return E_FatalError("No palette found.");
330
    if (!(paletteloaded & PALETTE_SHADE))
331
        return E_FatalError("No shade table found.");
332
    if (!(paletteloaded & PALETTE_TRANSLUC))
333
        return E_FatalError("No translucency table found.");
334
 
335
    E_PostLoadPalette();
336
 
337
    return 0;
338
}
339
 
340
void E_ReplaceTransparentColorWithBlack(void)
341
{
5829 terminx 342
    for (bssize_t i=0; i<MAXPALOOKUPS; i++)
5789 terminx 343
    {
344
        char * const thispalookup = palookup[i];
345
        if (thispalookup == NULL)
346
            continue;
347
 
5829 terminx 348
        for (bssize_t j=0; j<numshades; j++)
5789 terminx 349
        {
350
            thispalookup[(j<<8) + 255] = 255;
351
        }
352
    }
353
 
354
    // fix up translucency table so that transluc(255,x)
355
    // and transluc(x,255) is black instead of purple.
5829 terminx 356
    for (bssize_t i=0; i<MAXBLENDTABS; i++)
5789 terminx 357
    {
358
        char * const transluc = blendtable[i];
359
        if (transluc == NULL)
360
            continue;
361
 
5829 terminx 362
        for (bssize_t j=0; j<255; j++)
5789 terminx 363
        {
364
            transluc[(255<<8) + j] = transluc[(blackcol<<8) + j];
365
            transluc[255 + (j<<8)] = transluc[blackcol + (j<<8)];
366
        }
367
        transluc[(255<<8) + 255] = transluc[(blackcol<<8) + blackcol];
368
    }
369
}
370
 
371
// Load LOOKUP.DAT, which contains lookup tables and additional base palettes.
372
//
373
// <fp>: kopen4load file handle
374
//
375
// Returns:
376
//  - on success, 0
377
//  - on error, -1 (didn't read enough data)
378
//  - -2: error, we already wrote an error message ourselves
379
int32_t loadlookups(int32_t fp)
380
{
381
    uint8_t numlookups;
382
    char remapbuf[256];
383
 
384
    if (kread_and_test(fp, &numlookups, 1))
385
        return -1;
386
 
5829 terminx 387
    for (bssize_t j=0; j<numlookups; j++)
5789 terminx 388
    {
389
        uint8_t palnum;
390
 
391
        if (kread_and_test(fp, &palnum, 1))
392
            return -1;
393
 
394
        if (palnum >= 256-RESERVEDPALS)
395
        {
396
            initprintf("ERROR: attempt to load lookup at reserved pal %d\n", palnum);
397
            return -2;
398
        }
399
 
400
        if (kread_and_test(fp, remapbuf, 256))
401
            return -1;
402
 
403
        makepalookup(palnum, remapbuf, 0, 0, 0, 0);
404
    }
405
 
406
    return 0;
407
}
408
 
409
void generatefogpals(void)
410
{
411
    // Find a gap of four consecutive unused pal numbers to generate fog shade
412
    // tables.
5829 terminx 413
    for (bssize_t j=1; j<=255-3; j++)
5789 terminx 414
        if (!palookup[j] && !palookup[j+1] && !palookup[j+2] && !palookup[j+3])
415
        {
416
            makepalookup(j, NULL, 60, 60, 60, 1);
417
            makepalookup(j+1, NULL, 60, 0, 0, 1);
418
            makepalookup(j+2, NULL, 0, 60, 0, 1);
419
            makepalookup(j+3, NULL, 0, 0, 60, 1);
420
 
421
            break;
422
        }
423
}
424
 
425
void fillemptylookups(void)
426
{
427
    // Alias remaining unused pal numbers to the base shade table.
5829 terminx 428
    for (bssize_t j=1; j<MAXPALOOKUPS; j++)
5789 terminx 429
    {
430
        // If an existing lookup is identical to #0, free it.
431
        if (palookup[j] && palookup[j] != palookup[0] && !Bmemcmp(palookup[0], palookup[j], 256*numshades))
432
            removepalookup(j);
433
 
434
        if (!palookup[j])
435
            makepalookup(j, NULL, 0, 0, 0, 1);
436
    }
437
}
438
 
439
static int32_t palookup_isdefault(int32_t palnum)  // KEEPINSYNC engine.lua
440
{
441
    return (palookup[palnum] == NULL || (palnum!=0 && palookup[palnum] == palookup[0]));
442
}
443
 
444
static void maybe_alloc_palookup(int32_t palnum)
445
{
446
    if (palookup_isdefault(palnum))
447
    {
448
        alloc_palookup(palnum);
449
        if (palookup[palnum] == NULL)
450
            Bexit(1);
451
    }
452
}
453
 
454
void setblendtab(int32_t blend, const char *tab)
455
{
456
    if (blendtable[blend] == NULL)
457
        blendtable[blend] = (char *) Xmalloc(256*256);
458
 
459
    Bmemcpy(blendtable[blend], tab, 256*256);
460
}
461
void removeblendtab(int32_t const blend)
462
{
463
    DO_FREE_AND_NULL(blendtable[blend]);
464
}
465
 
466
#ifdef LUNATIC
467
const char *(getblendtab) (int32_t blend)
468
{
469
    return blendtable[blend];
470
}
471
#endif
472
 
5888 hendricks2 473
#ifdef USE_OPENGL
474
glblend_t const nullglblend =
475
{
476
    {
477
        { 1.f, BLENDFACTOR_ONE, BLENDFACTOR_ZERO, 0 },
478
        { 1.f, BLENDFACTOR_ONE, BLENDFACTOR_ZERO, 0 },
479
    },
480
};
481
glblend_t const defaultglblend =
482
{
483
    {
484
        { 2.f/3.f, BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 0 },
485
        { 1.f/3.f, BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 0 },
486
    },
487
};
488
 
489
glblend_t glblend[MAXBLENDTABS];
490
 
491
void handle_blend(uint8_t enable, uint8_t blend, uint8_t def)
492
{
493
    static GLenum const blendFuncTokens[NUMBLENDFACTORS] =
494
    {
495
        GL_ZERO,
496
        GL_ONE,
497
        GL_SRC_COLOR,
498
        GL_ONE_MINUS_SRC_COLOR,
499
        GL_SRC_ALPHA,
500
        GL_ONE_MINUS_SRC_ALPHA,
501
        GL_DST_ALPHA,
502
        GL_ONE_MINUS_DST_ALPHA,
503
        GL_DST_COLOR,
504
        GL_ONE_MINUS_DST_COLOR,
505
    };
506
 
507
    if (!enable)
508
    {
509
        bglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
510
        return;
511
    }
512
 
513
    glblenddef_t const * const glbdef = glblend[blend].def + def;
514
    bglBlendFunc(blendFuncTokens[glbdef->src], blendFuncTokens[glbdef->dst]);
515
}
516
#endif
517
 
5789 terminx 518
int32_t setpalookup(int32_t palnum, const uint8_t *shtab)
519
{
520
    if (numshades != 32)
521
        return -1;
522
 
523
    if (shtab != NULL)
524
    {
525
        maybe_alloc_palookup(palnum);
526
        Bmemcpy(palookup[palnum], shtab, 256*numshades);
527
    }
528
 
529
    return 0;
530
}
531
void removepalookup(int32_t const palnum)
532
{
533
    if (palnum == 0 && palookup[palnum] != NULL)
534
    {
5829 terminx 535
        for (bssize_t i = 1; i < MAXPALOOKUPS; i++)
5789 terminx 536
            if (palookup[i] == palookup[palnum])
537
                palookup[i] = NULL;
538
 
539
        DO_FREE_AND_NULL(palookup[palnum]);
540
    }
541
    else if (palookup[palnum] == palookup[0])
542
        palookup[palnum] = NULL;
543
    else
544
        DO_FREE_AND_NULL(palookup[palnum]);
545
}
546
 
547
//
548
// makepalookup
549
//
550
void makepalookup(int32_t palnum, const char *remapbuf, uint8_t r, uint8_t g, uint8_t b, char noFloorPal)
551
{
552
    int32_t i, j;
553
 
554
    static char idmap[256] ={ 1 };
555
 
556
    if (paletteloaded == 0)
557
        return;
558
 
559
    // NOTE: palnum==0 is allowed
560
    if ((unsigned) palnum >= MAXPALOOKUPS)
561
        return;
562
 
563
    g_noFloorPal[palnum] = noFloorPal;
564
 
565
    if (remapbuf==NULL)
566
    {
567
        if ((r|g|b) == 0)
568
        {
569
            palookup[palnum] = palookup[0];  // Alias to base shade table!
570
            return;
571
        }
572
 
573
        if (idmap[0]==1)  // init identity map
574
            for (i=0; i<256; i++)
575
                idmap[i] = i;
576
 
577
        remapbuf = idmap;
578
    }
579
 
580
    maybe_alloc_palookup(palnum);
581
 
582
    if ((r|g|b) == 0)
583
    {
584
        // "black fog"/visibility case -- only remap color indices
585
 
586
        for (j=0; j<numshades; j++)
587
            for (i=0; i<256; i++)
588
            {
589
                const char *src = palookup[0];
590
                palookup[palnum][256*j + i] = src[256*j + remapbuf[i]];
591
            }
592
    }
593
    else
594
    {
595
        // colored fog case
596
 
597
        char *ptr2 = palookup[palnum];
598
 
599
        for (i=0; i<numshades; i++)
600
        {
601
            int32_t palscale = divscale16(i, numshades-1);
602
 
603
            for (j=0; j<256; j++)
604
            {
605
                const char *ptr = (const char *) &palette[remapbuf[j]*3];
606
                *ptr2++ = getclosestcol(ptr[0] + mulscale16(r-ptr[0], palscale),
607
                    ptr[1] + mulscale16(g-ptr[1], palscale),
608
                    ptr[2] + mulscale16(b-ptr[2], palscale));
609
            }
610
        }
611
    }
612
 
613
#if defined(USE_OPENGL)
614
    palookupfog[palnum].r = r;
615
    palookupfog[palnum].g = g;
616
    palookupfog[palnum].b = b;
617
#endif
618
}
619
 
620
//
621
// setbasepal
622
//
623
void setbasepal(int32_t id, uint8_t const * const table)
624
{
625
    if (basepaltable[id] == NULL)
626
        basepaltable[id] = (uint8_t *) Xmalloc(768);
627
 
628
    Bmemcpy(basepaltable[id], table, 768);
629
}
630
void removebasepal(int32_t const id)
631
{
632
    if (id == 0)
633
        Bmemset(basepaltable[id], 0, 768);
634
    else
635
        DO_FREE_AND_NULL(basepaltable[id]);
636
}
637
 
638
//
639
// setbrightness
640
//
641
// flags:
642
//  1: don't setpalette(),  DON'T USE THIS FLAG!
643
//  2: don't gltexinvalidateall()
644
//  4: don't calc curbrightness from dabrightness,  DON'T USE THIS FLAG!
645
//  8: don't gltexinvalidate8()
646
// 16: don't reset palfade*
647
void setbrightness(char dabrightness, uint8_t dapalid, uint8_t flags)
648
{
5884 terminx 649
    int32_t i, j;
5789 terminx 650
    const uint8_t *dapal;
651
 
652
#ifdef USE_OPENGL
653
    int32_t paldidchange;
654
#endif
655
    int32_t palsumdidchange;
656
    //    uint32_t lastbright = curbrightness;
657
 
658
    Bassert((flags&4)==0);
659
 
660
    if (/*(unsigned)dapalid >= MAXBASEPALS ||*/ basepaltable[dapalid] == NULL)
661
        dapalid = 0;
662
#ifdef USE_OPENGL
663
    paldidchange = (curbasepal != dapalid || basepalreset);
664
#endif
665
    curbasepal = dapalid;
666
    basepalreset = 0;
667
 
668
    dapal = basepaltable[curbasepal];
669
 
670
    if (!(flags&4))
671
    {
672
        curbrightness = clamp(dabrightness, 0, 15);
673
        //        if (lastbright != (unsigned)curbrightness)
674
        //            vid_gamma = 1.0 + ((float)curbrightness / 10.0);
675
    }
676
 
5884 terminx 677
    setgamma();
678
    j = !gammabrightness ? curbrightness : 0;
5789 terminx 679
 
680
    for (i=0; i<256; i++)
681
    {
682
        // save palette without any brightness adjustment
683
        curpalette[i].r = dapal[i*3+0];
684
        curpalette[i].g = dapal[i*3+1];
685
        curpalette[i].b = dapal[i*3+2];
686
        curpalette[i].f = 0;
687
 
688
        // brightness adjust the palette
689
        curpalettefaded[i].b = britable[j][curpalette[i].b];
690
        curpalettefaded[i].g = britable[j][curpalette[i].g];
691
        curpalettefaded[i].r = britable[j][curpalette[i].r];
692
        curpalettefaded[i].f = 0;
693
    }
694
 
695
    if ((flags&16) && palfadedelta)  // keep the fade
696
        setpalettefade_calc(palfadedelta>>2);
697
 
698
    {
699
        static uint32_t lastpalettesum=0;
700
        uint32_t newpalettesum = XXH32((uint8_t *) curpalettefaded, sizeof(curpalettefaded), sizeof(curpalettefaded));
701
 
702
        palsumdidchange = (newpalettesum != lastpalettesum);
703
 
704
        if (palsumdidchange || newpalettesum != g_lastpalettesum)
705
        {
706
            //            if ((flags&1) == 0)
707
            setpalette(0, 256);
708
        }
709
 
710
        g_lastpalettesum = lastpalettesum = newpalettesum;
711
    }
712
 
713
#ifdef USE_OPENGL
714
    if (getrendermode() >= REND_POLYMOST)
715
    {
716
        // Only reset the textures if the corresponding preserve flags are clear and
717
        // either (a) the new palette is different to the last, or (b) the brightness
718
        // changed and we couldn't set it using hardware gamma.
719
 
720
        // XXX: no-HW-gamma OpenGL platforms will exhibit bad performance with
721
        // simultaneous basepal and tint changes?
5884 terminx 722
        const int32_t doinvalidate = (paldidchange || (palsumdidchange && !gammabrightness));
5789 terminx 723
 
724
        if (!(flags&2) && doinvalidate)
725
            gltexinvalidatetype(INVALIDATE_ALL);
726
        if (!(flags&8) && doinvalidate)
727
            gltexinvalidatetype(INVALIDATE_ART);
728
#ifdef POLYMER
729
        if ((getrendermode() == REND_POLYMER) && doinvalidate)
730
            polymer_texinvalidate();
731
#endif
732
    }
733
#endif
734
 
735
    if ((flags&16)==0)
736
    {
737
        palfadergb.r = palfadergb.g = palfadergb.b = 0;
738
        palfadedelta = 0;
739
    }
740
}
741
 
5804 terminx 742
palette_t getpal(int32_t col)
5789 terminx 743
{
744
    if (!gammabrightness)
745
    {
5884 terminx 746
        palette_t const p = { britable[curbrightness][curpalette[col].r], britable[curbrightness][curpalette[col].g],
747
                              britable[curbrightness][curpalette[col].b], 0 };
5789 terminx 748
        return p;
749
    }
750
 
751
    return curpalette[col];
752
}
753
 
754
static void setpalettefade_calc(uint8_t offset)
755
{
756
    int32_t i;
757
    palette_t p;
758
 
759
    for (i=0; i<256; i++)
760
    {
761
        p = getpal(i);
762
 
763
        curpalettefaded[i].b =
764
            p.b + (((palfadergb.b - p.b) * offset) >> 8);
765
        curpalettefaded[i].g =
766
            p.g + (((palfadergb.g - p.g) * offset) >> 8);
767
        curpalettefaded[i].r =
768
            p.r + (((palfadergb.r - p.r) * offset) >> 8);
769
        curpalettefaded[i].f = 0;
770
    }
771
}
772
 
773
//#define DEBUG_PALETTEFADE
774
 
775
//
776
// setpalettefade
777
//
778
void setpalettefade(uint8_t r, uint8_t g, uint8_t b, uint8_t offset)
779
{
780
    palfadergb.r = r;
781
    palfadergb.g = g;
782
    palfadergb.b = b;
783
#ifdef DEBUG_PALETTEFADE
784
    if (offset)
785
        offset = max(offset, 128);
786
#endif
787
    palfadedelta = offset;
788
 
789
    setpalettefade_calc(offset);
790
 
791
    {
792
        static uint32_t lastpalettesum=0;
793
        uint32_t newpalettesum = XXH32((uint8_t *) curpalettefaded, sizeof(curpalettefaded), sizeof(curpalettefaded));
794
 
795
        if (newpalettesum != lastpalettesum || newpalettesum != g_lastpalettesum)
796
            setpalette(0, 256);
797
 
798
        g_lastpalettesum = lastpalettesum = newpalettesum;
799
    }
800
}