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/fl8cply.c $
21  * $Revision: 1.2 $
22  * $Author: kevin $
23  * $Date: 1994/10/17 14:59:58 $
24  *
25  * Routines for drawing flat shaded polygons onto a flat 8 canvas.
26  *
27  * This file is part of the 2d library.
28  */
29 
30 #include "cnvdat.h"
31 #include "fix.h"
32 #include "gente.h"
33 #include "poly.h"
34 #include "rgb.h"
35 #include "scrdat.h"
36 #include "tmapint.h"
37 
38 // prototypes
39 int gri_cpoly_loop(grs_tmap_loop_info *ti);
40 void gri_cpoly_init(grs_tmap_loop_info *ti);
41 void gri_clut_cpoly_init(grs_tmap_loop_info *ti);
42 
gri_cpoly_loop(grs_tmap_loop_info * ti)43 int gri_cpoly_loop(grs_tmap_loop_info *ti) {
44     int x, d;
45     fix dx, frac;
46     fix r, g, b, dr, dg, db;
47 
48     do {
49         dx = ti->right.x - ti->left.x;
50         frac = fix_ceil(ti->left.x) - ti->left.x;
51 
52         r = ti->left.u;
53         dr = fix_div(ti->right.u - r, dx);
54         r += fix_mul(frac, dr);
55 
56         g = ti->left.v;
57         dg = fix_div(ti->right.v - g, dx);
58         g += fix_mul(frac, dg);
59 
60         b = ti->left.i;
61         db = fix_div(ti->right.i - b, dx);
62         b += fix_mul(frac, db);
63 
64         if ((d = fix_cint(ti->right.x) - fix_cint(ti->left.x)) > 0) {
65             switch (ti->bm.hlog) {
66             case GRL_OPAQUE:
67                 for (x = fix_cint(ti->left.x); x < fix_cint(ti->right.x); x++) {
68                     int j = gr_index_rgb(r, g, b);
69                     ti->d[x] = grd_ipal[j];
70                     r += dr, g += dg, b += db;
71                 }
72                 break;
73             case GRL_CLUT:
74                 for (x = fix_cint(ti->left.x); x < fix_cint(ti->right.x); x++) {
75                     int j = gr_index_rgb(r, g, b);
76                     ti->d[x] = ti->clut[grd_ipal[j]];
77                     r += dr, g += dg, b += db;
78                 }
79                 break;
80             }
81         } else if (d < 0) {
82             return TRUE;
83         }
84         /* update span extrema and destination. */
85         ti->left.x += ti->left.dx;
86         ti->right.x += ti->right.dx;
87         ti->left.u += ti->left.du;
88         ti->right.u += ti->right.du;
89         ti->left.v += ti->left.dv;
90         ti->right.v += ti->right.dv;
91         ti->left.i += ti->left.di;
92         ti->right.i += ti->right.di;
93         ti->d += grd_bm.row;
94     } while ((--(ti->n)) > 0);
95     return FALSE;
96 }
97 
gri_cpoly_init(grs_tmap_loop_info * ti)98 void gri_cpoly_init(grs_tmap_loop_info *ti) {
99     ti->bm.hlog = GRL_OPAQUE;
100     ti->d = ti->y * grd_bm.row + grd_bm.bits;
101     ti->loop_func = (void (*)())gri_cpoly_loop;
102     ti->top_edge_func = (void (*)())gri_rgbx_edge;
103     ti->bot_edge_func = (void (*)())gri_rgbx_edge;
104 }
105 
gri_clut_cpoly_init(grs_tmap_loop_info * ti)106 void gri_clut_cpoly_init(grs_tmap_loop_info *ti) {
107     ti->bm.hlog = GRL_CLUT;
108     ti->d = ti->y * grd_bm.row + grd_bm.bits;
109     ti->loop_func = (void (*)())gri_cpoly_loop;
110     ti->top_edge_func = (void (*)())gri_rgbx_edge;
111     ti->bot_edge_func = (void (*)())gri_rgbx_edge;
112 }
113