Subversion Repositories eduke32

Rev

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