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