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/fl8nl.c $
21  * $Revision: 1.3 $
22  * $Author: kevin $
23  * $Date: 1994/08/16 13:12:41 $
24  *
25  * Routines to linearly texture map a flat8 bitmap to a generic canvas.
26  *
27  * This file is part of the 2d library.
28  *
29  */
30 
31 #include "cnvdat.h"
32 #include "fl8tf.h"
33 #include "fl8tmapdv.h"
34 #include "gente.h"
35 #include "plytyp.h"
36 #include "poly.h"
37 #include "tlucdat.h"
38 #include "tmapint.h"
39 #include "vtab.h"
40 
41 // prototypes
42 int gri_tluc8_lin_umap_loop(grs_tmap_loop_info *tli);
43 
gri_tluc8_lin_umap_loop(grs_tmap_loop_info * tli)44 int gri_tluc8_lin_umap_loop(grs_tmap_loop_info *tli)
45 {
46   fix u = tli->left.u, du = tli->right.u - u;
47   fix v = tli->left.v, dv = tli->right.v - v;
48   int32_t *t_vtab = tli->vtab;
49   uchar *t_bits = tli->bm.bits;
50   uchar *t_clut = tli->clut;
51   uint32_t t_mask = tli->mask;
52   uchar t_wlog = tli->bm.wlog;
53   uchar temp_pix;
54 
55   while (tli->n)
56   {
57     fix dx = tli->right.x - tli->left.x;
58     if (dx <= 0) return TRUE; //might divide by zero below; punt this tmap
59 
60     uchar *p       = tli->d + fix_cint(tli->left.x);
61     uchar *p_final = tli->d + fix_cint(tli->right.x);
62 
63     du = fix_div(du, dx);
64     dv = fix_div(dv, dx);
65 
66     switch (tli->bm.hlog)
67     {
68       case GRL_OPAQUE:
69         for (; p < p_final; p++)
70         {
71           int k = t_vtab[fix_fint(v)] + fix_fint(u);
72           k = t_bits[k];
73           if (tluc8tab[k] != NULL) *p = tluc8tab[k][*p]; else *p = k;
74           u += du;
75           v += dv;
76         }
77       break;
78 
79       case GRL_TRANS:
80         for (; p < p_final; p++)
81         {
82           int k = t_vtab[fix_fint(v)] + fix_fint(u);
83           k = t_bits[k];
84           if (k != 0) {
85             if (tluc8tab[k] != NULL) *p = tluc8tab[k][*p]; else *p = k;
86           }
87           u += du;
88           v += dv;
89         }
90       break;
91 
92       case GRL_OPAQUE | GRL_LOG2:
93         for (; p < p_final; p++)
94         {
95           int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
96           k = t_bits[k];
97           if (tluc8tab[k] != NULL) *p = tluc8tab[k][*p]; else *p = k;
98           u += du;
99           v += dv;
100         }
101       break;
102 
103       case GRL_TRANS | GRL_LOG2:
104         for (; p < p_final; p++)
105         {
106           int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
107           k = t_bits[k];
108           if (k != 0) {
109             if (tluc8tab[k] != NULL) *p = tluc8tab[k][*p]; else *p = k;
110           }
111           u += du;
112           v += dv;
113         }
114       break;
115 
116       case GRL_OPAQUE | GRL_CLUT:
117         for (; p < p_final; p++)
118         {
119           int k = t_vtab[fix_fint(v)] + fix_fint(u);
120           k = t_bits[k];
121           if (tluc8tab[k] != NULL) *p = t_clut[tluc8tab[k][*p]]; else *p = t_clut[k];
122           u += du;
123           v += dv;
124         }
125       break;
126 
127       case GRL_TRANS | GRL_CLUT:
128         for (; p < p_final; p++)
129         {
130           int k = t_vtab[fix_fint(v)] + fix_fint(u);
131           k = t_bits[k];
132           if (k != 0) {
133             if (tluc8tab[k] != NULL) *p = t_clut[tluc8tab[k][*p]]; else *p = t_clut[k];
134           }
135           u += du;
136           v += dv;
137         }
138       break;
139 
140       case GRL_OPAQUE | GRL_LOG2 | GRL_CLUT:
141         for (; p < p_final; p++)
142         {
143           int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
144           k = t_bits[k];
145           if (tluc8tab[k] != NULL) *p = t_clut[tluc8tab[k][*p]]; else *p = t_clut[k];
146           u += du;
147           v += dv;
148         }
149       break;
150 
151       case GRL_TRANS | GRL_LOG2 | GRL_CLUT:
152         for (; p < p_final; p++)
153         {
154           int k = ((fix_fint(v) << t_wlog) + fix_fint(u)) & t_mask;
155           k = t_bits[k];
156           if (k != 0) {
157             if (tluc8tab[k] != NULL) *p = t_clut[tluc8tab[k][*p]]; else *p = t_clut[k];
158           }
159           u += du;
160           v += dv;
161         }
162       break;
163     }
164 
165     u = (tli->left.u += tli->left.du);
166     tli->right.u += tli->right.du;
167     du = tli->right.u - u;
168 
169     v = (tli->left.v += tli->left.dv);
170     tli->right.v += tli->right.dv;
171     dv = tli->right.v - v;
172 
173     tli->left.x += tli->left.dx;
174     tli->right.x += tli->right.dx;
175 
176     tli->d += grd_bm.row;
177     tli->n --;
178   }
179 
180   return FALSE; //tmap OK
181 }
182 
gri_tluc8_trans_lin_umap_init(grs_tmap_loop_info * tli)183 void gri_tluc8_trans_lin_umap_init(grs_tmap_loop_info *tli) {
184     if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
185         tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
186         tli->bm.hlog = GRL_TRANS | GRL_LOG2;
187     } else {
188         tli->vtab = gr_make_vtab(&(tli->bm));
189         tli->bm.hlog = GRL_TRANS;
190     }
191     tli->d = grd_bm.bits + grd_bm.row * tli->y;
192     tli->loop_func = (void (*)())gri_tluc8_lin_umap_loop;
193     tli->right_edge_func = (void (*)())gri_uvx_edge;
194     tli->left_edge_func = (void (*)())gri_uvx_edge;
195 }
196 
gri_tluc8_opaque_lin_umap_init(grs_tmap_loop_info * tli)197 void gri_tluc8_opaque_lin_umap_init(grs_tmap_loop_info *tli) {
198     if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
199         tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
200         tli->bm.hlog = GRL_OPAQUE | GRL_LOG2;
201     } else {
202         tli->vtab = gr_make_vtab(&(tli->bm));
203         tli->bm.hlog = GRL_OPAQUE;
204     }
205     tli->d = grd_bm.bits + grd_bm.row * tli->y;
206     tli->loop_func = (void (*)())gri_tluc8_lin_umap_loop;
207     tli->right_edge_func = (void (*)())gri_uvx_edge;
208     tli->left_edge_func = (void (*)())gri_uvx_edge;
209 }
210 
gri_tluc8_trans_clut_lin_umap_init(grs_tmap_loop_info * tli)211 void gri_tluc8_trans_clut_lin_umap_init(grs_tmap_loop_info *tli) {
212     if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
213         tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
214         tli->bm.hlog = GRL_TRANS | GRL_LOG2 | GRL_CLUT;
215     } else {
216         tli->vtab = gr_make_vtab(&(tli->bm));
217         tli->bm.hlog = GRL_TRANS | GRL_CLUT;
218     }
219     tli->d = grd_bm.bits + grd_bm.row * tli->y;
220     tli->loop_func = (void (*)())gri_tluc8_lin_umap_loop;
221     tli->right_edge_func = (void (*)())gri_uvx_edge;
222     tli->left_edge_func = (void (*)())gri_uvx_edge;
223 }
224 
gri_tluc8_opaque_clut_lin_umap_init(grs_tmap_loop_info * tli)225 void gri_tluc8_opaque_clut_lin_umap_init(grs_tmap_loop_info *tli) {
226     if ((tli->bm.row == (1 << tli->bm.wlog)) && (tli->bm.h == (1 << tli->bm.hlog))) {
227         tli->mask = (1 << (tli->bm.hlog + tli->bm.wlog)) - 1;
228         tli->bm.hlog = GRL_OPAQUE | GRL_LOG2 | GRL_CLUT;
229     } else {
230         tli->vtab = gr_make_vtab(&(tli->bm));
231         tli->bm.hlog = GRL_OPAQUE | GRL_CLUT;
232     }
233     tli->d = grd_bm.bits + grd_bm.row * tli->y;
234     tli->loop_func = (void (*)())gri_tluc8_lin_umap_loop;
235     tli->right_edge_func = (void (*)())gri_uvx_edge;
236     tli->left_edge_func = (void (*)())gri_uvx_edge;
237 }
238