1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 /*
20 * $Source: r:/prj/lib/src/2d/RCS/blend.c $
21 * $Revision: 1.2 $
22 * $Author: kevin $
23 * $Date: 1994/09/08 21:57:25 $
24 *
25 * Support for creation and maintenance of blend tables
26 *
27 * This file is part of the 2d library.
28 */
29
30 #include "grs.h"
31 #include "blncon.h"
32 #include "rgb.h"
33 #include "scrdat.h"
34
35 // prototypes
36 void gri_build_blend(uchar *base_addr, int blend_fac);
37 int gr_free_blend(void);
38 uchar gr_init_blend(int log_blend_levels);
39
40
41 // points to blend_tabs-1 tables, each 64k
42 uchar *grd_blend=NULL;
43 uchar *grd_half_blend=NULL;
44 int grd_log_blend_levels=0;
45
46 // blend fac is 0-256, where 0 is all 0, 256 is all 1
gri_build_blend(uchar * base_addr,int blend_fac)47 void gri_build_blend(uchar *base_addr, int blend_fac)
48 {
49 uchar *c=grd_ipal, *cur_addr=base_addr, cols[2][3];
50 int offs, i, j, k; /* offset from ipal for data, loop controls */
51 int blend_bar=GR_BLEND_TABLE_RES-blend_fac; /* remaining blend frac */
52
53 for (i=0; i<256; i++)
54 {
55 gr_split_rgb(grd_bpal[i],&cols[0][0],&cols[0][1],&cols[0][2]);
56 for (j=0; j<256; j++)
57 {
58 if ((i==0)||(i==j)||(cols[0][0]+cols[0][1]+cols[0][2]==0))
59 *cur_addr++=i; // transparency and self and black are themselves, for zaniness w/shifts
60 else
61 {
62 gr_split_rgb(grd_bpal[j],&cols[1][0],&cols[1][1],&cols[1][2]);
63 if ((j==0)||(cols[1][0]+cols[1][1]+cols[1][2]==0))
64 *cur_addr++=j;
65 else
66 {
67 for (offs=0, k=2; k>=0; k--) // go do the blends
68 offs=(offs<<5)+((((cols[0][k]*blend_bar)+(cols[1][k]*blend_fac))>>GR_BLEND_TABLE_RES_LOG)>>3);
69 *cur_addr++=*(c+offs);
70 }
71 }
72 }
73 }
74 }
75
76 /* frees the blending table. returns 0 if ok, nonzero if error. */
gr_free_blend(void)77 int gr_free_blend(void)
78 {
79 if (grd_blend==NULL)
80 return 1;
81 free( grd_blend); // was gr_free
82 grd_blend=NULL;
83 grd_log_blend_levels=0;
84 return 0;
85 }
86
87 // at the moment, log_blend_levels = 0 deallocates the blend, ie. runs free_blend
gr_init_blend(int log_blend_levels)88 uchar gr_init_blend(int log_blend_levels)
89 {
90 if (log_blend_levels>0)
91 {
92 int fac=GR_BLEND_TABLE_RES>>log_blend_levels; /* base blend factor*/
93 int tab_cnt=(1<<log_blend_levels)-1, i; /* number of tables, loop control */
94
95 if (grd_blend!=NULL) if (!gr_free_blend()) return FALSE; /* something went horribly wrong */
96 // if ((grd_blend=(uchar *) gr_malloc(tab_cnt*GR_BLEND_TABLE_SIZE))==NULL) return FALSE; /* x 64k tables */
97 if ((grd_blend=(uchar *) malloc(tab_cnt*GR_BLEND_TABLE_SIZE))==NULL) return FALSE; /* x 64k tables */
98 for (i=0; i<tab_cnt; i++)
99 gri_build_blend(grd_blend+(i*GR_BLEND_TABLE_SIZE),fac*(i+1));
100 grd_log_blend_levels=log_blend_levels;
101 grd_half_blend=grd_blend+(tab_cnt>>1)*GR_BLEND_TABLE_SIZE;
102 return TRUE;
103 }
104 else return gr_free_blend();
105 }
106