Subversion Repositories eduke32

Rev

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