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/fl8lin.c $
21  * $Revision: 1.11 $
22  * $Author: lmfeeney $
23  * $Date: 1994/08/12 01:09:59 $
24  *
25  * Routines for drawing fixed-point lines onto a flat 8 canvas.
26  *
27  * This file is part of the 2d library.
28  *
29  * $Log: fl8lin.c $
30  * Revision 1.11  1994/08/12  01:09:59  lmfeeney
31  * get  fill/solid parm from right place
32  *
33  * Revision 1.10  1994/06/11  01:22:44  lmfeeney
34  * guts of the routine moved to fl8{c,s}lin.h, per fill type
35  * line drawers are created by defining macros and including
36  * this file
37  *
38  * Revision 1.9  1994/05/06  18:18:58  lmfeeney
39  * rewritten for greater accuracy
40  *
41  * Revision 1.8  1993/12/15  11:25:22  kaboom
42  * Fixed up problems with not including endpoints and to match up with
43  * new polygon scanner.
44  *
45  * Revision 1.7  1993/10/19  09:50:35  kaboom
46  * Replaced #include "grd.h" with new headers split from grd.h.
47  *
48  * Revision 1.6  1993/10/08  01:15:18  kaboom
49  * Changed quotes in #include liness to angle brackets for Watcom problem.
50  *
51  * Revision 1.5  1993/06/23  04:56:07  kaboom
52  * Put in checks for single-pixel horizontal and vertical lines.
53  *
54  * Revision 1.4  1993/06/22  15:14:38  kaboom
55  * Now checks to see if final span is empty.
56  *
57  * Revision 1.3  1993/06/16  18:15:24  kaboom
58  * Removed foolish mprintfs accidentally left in.
59  *
60  * Revision 1.2  1993/06/16  01:59:53  kaboom
61  * Fixed gradual precision error.  Last span now explicitly set to x1
62  * instead of adding m_inv.
63  *
64  * Revision 1.1  1993/03/02  20:33:50  kaboom
65  * Initial revision
66  */
67 
68 #include "cnvdat.h"
69 #include "ctxmac.h"
70 #include "fill.h"
71 #include "fix.h"
72 #include "lg.h"
73 #include "plytyp.h"
74 #include "scrdat.h"
75 #include <string.h>
76 
77 /* This particular mess implements the fix_uline for each of the
78    five fill types.  The main driver (essentially the code in the
79    the 'original' fl8lin.c) is now a code fragment in fl8lin.h
80 
81    For each function, four macros are (re)defined - flat8_pixel_fill_xf
82    and flat8_pixel_fill_xi - which set the pixel value in the case of
83    x fix-point and x known to be integer, and flat8_pixel_fill_row, which
84    allows us to retain the speed hack for a (nearly) horizontal line.  For
85    fill types which are indep of the pixel value (norm, solid, clut), the
86    color is set only once in flat8_pixel_fill_init.
87 
88    Note that each macro is referenced 7 times (the line drawer has
89    lots of dx <=> dy type cases).  This makes blend come out huge.
90 
91    None of these macros take arguments, instead they rely on secret
92    gnosis of the variable names in fl8lin.h
93 */
94 
95 /* not all line fill functions use all their parameters */
96 // MLA #pragma off (unreferenced)
97 
98 /* same for norm, solid and clut */
99 
100 #undef flat8_pixel_fill_xf
101 #define flat8_pixel_fill_xf  \
102     do {                     \
103         p[fix_fint(x0)] = c; \
104     } while (0)
105 
106 #undef flat8_pixel_fill_xi
107 #define flat8_pixel_fill_xi \
108     do {                    \
109         p[x0] = c;          \
110     } while (0)
111 
112 #undef flat8_pixel_fill_row
113 #define flat8_pixel_fill_row               \
114     do {                                   \
115         LG_memset(p + x0, c, x1 - x0 + 1); \
116     } while (0)
117 
118 #undef flat8_pixel_fill_init
119 #define flat8_pixel_fill_init                 \
120     do {                                      \
121         if (gr_get_fill_type() == FILL_SOLID) \
122             c = (uchar)parm;                  \
123     } while (0)
124 
125 /* norm */
126 
gri_flat8_uline_ns(long c,long parm,grs_vertex * v0,grs_vertex * v1)127 void gri_flat8_uline_ns(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
128 #include "fl8lin.h"
129 }
130 
131     /* clut */
132 
133 #undef flat8_pixel_fill_init
134 #define flat8_pixel_fill_init           \
135     do {                                \
136         c = (long)(((uchar *)parm)[c]); \
137     } while (0)
138 
gri_flat8_uline_clut(long c,long parm,grs_vertex * v0,grs_vertex * v1)139 void gri_flat8_uline_clut(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
140 #include "fl8lin.h"
141 }
142 
143     /* xor */
144 
145 #undef flat8_pixel_fill_xf
146 #define flat8_pixel_fill_xf                    \
147     do {                                       \
148         p[fix_fint(x0)] = c ^ p[fix_fint(x0)]; \
149     } while (0)
150 
151 #undef flat8_pixel_fill_xi
152 #define flat8_pixel_fill_xi \
153     do {                    \
154         p[x0] = c ^ p[x0];  \
155     } while (0)
156 
157 #undef flat8_pixel_fill_row
158 #define flat8_pixel_fill_row     \
159     do {                         \
160         while (x0 < x1) {        \
161             flat8_pixel_fill_xi; \
162             x0++;                \
163         }                        \
164     } while (0)
165 
gri_flat8_uline_xor(long c,long parm,grs_vertex * v0,grs_vertex * v1)166 void gri_flat8_uline_xor(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
167 #include "fl8lin.h"
168 }
169 
170     /* blend -- maybe we should just swallow the function call */
171 
172 #define QMASK 0x3fc7f8ff
173 /* convert red in a glomped rgb to a fixed point */
174 #define rtof(b) (((b)&0x3ff) << 12)
175 /* convert green in a glomped rgb to a fixed point */
176 #define gtof(b) (((b)&0x1ff800) << 1)
177 /* convert blue in a glomped rgb to a fixed point */
178 #define btof(b) (((b)&0xffc00000) >> 10)
179 
180 #undef flat8_pixel_fill_xf
181 #define flat8_pixel_fill_xf                                                                \
182     do {                                                                                   \
183         uchar *k;                                                                          \
184         grs_rgb prev;                                                                      \
185         grs_rgb lg_new;                                                                    \
186         fix r1, g1, b1;                                                                    \
187                                                                                            \
188         prev = grd_bpal[p[fix_fint(x0)]];                                                  \
189         lg_new = grd_bpal[c];                                                              \
190                                                                                            \
191         r1 = fix_mul(rtof(lg_new), (fix)parm) + fix_mul(rtof(prev), FIX_UNIT - (fix)parm); \
192         g1 = fix_mul(gtof(lg_new), (fix)parm) + fix_mul(gtof(prev), FIX_UNIT - (fix)parm); \
193         b1 = fix_mul(btof(lg_new), (fix)parm) + fix_mul(btof(prev), FIX_UNIT - (fix)parm); \
194                                                                                            \
195         k = grd_ipal;                                                                      \
196         k += (r1 >> 17) & 0x1f;                                                            \
197         k += (g1 >> 12) & 0x3e0;                                                           \
198         k += (b1 >> 7) & 0x7c00;                                                           \
199         p[fix_fint(x0)] = *k;                                                              \
200     } while (0)
201 
202 #undef flat8_pixel_fill_xi
203 #define flat8_pixel_fill_xi                                                                \
204     do {                                                                                   \
205         uchar *k;                                                                          \
206         grs_rgb prev;                                                                      \
207         grs_rgb lg_new;                                                                    \
208         fix r1, g1, b1;                                                                    \
209                                                                                            \
210         prev = grd_bpal[p[x0]];                                                            \
211         lg_new = grd_bpal[c];                                                              \
212                                                                                            \
213         r1 = fix_mul(rtof(lg_new), (fix)parm) + fix_mul(rtof(prev), FIX_UNIT - (fix)parm); \
214         g1 = fix_mul(gtof(lg_new), (fix)parm) + fix_mul(gtof(prev), FIX_UNIT - (fix)parm); \
215         b1 = fix_mul(btof(lg_new), (fix)parm) + fix_mul(btof(prev), FIX_UNIT - (fix)parm); \
216                                                                                            \
217         k = grd_ipal;                                                                      \
218         k += (r1 >> 17) & 0x1f;                                                            \
219         k += (g1 >> 12) & 0x3e0;                                                           \
220         k += (b1 >> 7) & 0x7c00;                                                           \
221         p[x0] = *k;                                                                        \
222     } while (0)
223 
224 #undef flat8_pixel_fill_row
225 #define flat8_pixel_fill_row     \
226     do {                         \
227         while (x0 < x1) {        \
228             flat8_pixel_fill_xi; \
229             x0++;                \
230         }                        \
231     } while (0)
232 
233 #undef flat8_pixel_fill_init
234 #define flat8_pixel_fill_init \
235     do {                      \
236         ;                     \
237     } while (0)
238 
gri_flat8_uline_blend(long c,long parm,grs_vertex * v0,grs_vertex * v1)239 void gri_flat8_uline_blend(long c, long parm, grs_vertex *v0, grs_vertex *v1) {
240 #include "fl8lin.h"
241 }
242