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