Subversion Repositories eduke32

Rev

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