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/fl8s.asm $
21 // $Revision: 1.1 $
22 // $Author: kevin $
23 // $Date: 1994/08/16 12:34:32 $
24 //
25 // Inner loops of scaling and clut scaling primitives.
26 //
27 // This file is part of the 2d library.
28 //
29 
30 #include "cnvdat.h"
31 #include "gente.h"
32 #include "grnull.h"
33 #include "poly.h"
34 #include "tmapint.h"
35 
36 // globals
37 long ADD_DEST_OFF;
38 long ADD_DV_FRAC_OFF;
39 long AND_BM_ROW_OFF;
40 long ADD_SRC_OFF;
41 long SET_REPS_OFF;
42 long SET_OFFSET_OFF;
43 long JMP_LOOP_MIDDLE_OFF;
44 
45 #define unroll_num 4
46 #define unroll_log 2
47 
48 // externs
49 extern int gri_poly_loop(grs_tmap_loop_info *ti);
50 
51 // internal prototypes
52 int gri_scale_umap_loop_PPC(grs_tmap_loop_info *tli);
53 int gri_scale_umap_loop_68K(grs_tmap_loop_info *tli);
54 
55 // This file contains the scalers for both 68K and PowerPC
56 // First the routines that are generic to both, then the PowerPC routines, then
57 // 68K
58 
59 // ------------------------------------------------------------------------
60 // Generic (68K & PowerPC) routines
61 // ------------------------------------------------------------------------
62 
63 // ========================================================================
64 // opaque solid polygon scaler
gri_opaque_solid_scale_umap_init(grs_tmap_loop_info * info,grs_vertex ** vert)65 int gri_opaque_solid_scale_umap_init(grs_tmap_loop_info *info, grs_vertex **vert) {
66     info->left_edge_func = (void (*)())gri_scale_edge;
67     info->right_edge_func = (void (*)())gr_null;
68     info->bm.hlog = 0;
69     info->bm.bits = info->clut;
70     info->loop_func = (void (*)())gri_poly_loop;
71     info->d = ((uchar *)((long)grd_canvas->bm.row * (long)info->y));
72     info->d += (long)grd_canvas->bm.bits;
73     return (0);
74 }
75 
76 // ------------------------------------------------------------------------
77 // PowerPC routines
78 // ------------------------------------------------------------------------
79 // ========================================================================
80 // transparent solid polygon scaler
gri_trans_solid_scale_umap_init(grs_tmap_loop_info * tli,grs_vertex ** vert)81 int gri_trans_solid_scale_umap_init(grs_tmap_loop_info *tli, grs_vertex **vert) {
82     tli->bm.hlog = GRL_TRANS | GRL_SOLID;
83     tli->loop_func = (void (*)())gri_scale_umap_loop_PPC;
84     tli->right_edge_func = gr_null;
85     tli->left_edge_func = (void (*)())gri_scale_edge;
86     return (0);
87 }
88 
89 // ========================================================================
90 // transparent bitmap scaler
gri_trans_scale_umap_init(grs_tmap_loop_info * tli,grs_vertex ** vert)91 int gri_trans_scale_umap_init(grs_tmap_loop_info *tli, grs_vertex **vert) {
92     tli->bm.hlog = GRL_TRANS;
93     tli->loop_func = (void (*)())gri_scale_umap_loop_PPC;
94     tli->right_edge_func = gr_null;
95     tli->left_edge_func = (void (*)())gri_scale_edge;
96     return (0);
97 }
98 
99 // ========================================================================
100 // opaque bitmap scaler
gri_opaque_scale_umap_init(grs_tmap_loop_info * tli)101 int gri_opaque_scale_umap_init(grs_tmap_loop_info *tli) {
102     tli->bm.hlog = GRL_OPAQUE;
103     tli->loop_func = (void (*)())gri_scale_umap_loop_PPC;
104     tli->right_edge_func = gr_null;
105     tli->left_edge_func = (void (*)())gri_scale_edge;
106     return (0);
107 }
108 
109 // ========================================================================
110 // transparent clut bitmap scaler
gri_trans_clut_scale_umap_init(grs_tmap_loop_info * tli)111 int gri_trans_clut_scale_umap_init(grs_tmap_loop_info *tli) {
112     tli->bm.hlog = GRL_TRANS | GRL_CLUT;
113     tli->loop_func = (void (*)())gri_scale_umap_loop_PPC;
114     tli->right_edge_func = gr_null;
115     tli->left_edge_func = (void (*)())gri_scale_edge;
116     return (0);
117 }
118 
119 // ========================================================================
120 // opaque clut bitmap scaler
gri_opaque_clut_scale_umap_init(grs_tmap_loop_info * tli)121 int gri_opaque_clut_scale_umap_init(grs_tmap_loop_info *tli) {
122     tli->bm.hlog = GRL_OPAQUE | GRL_CLUT;
123     tli->loop_func = (void (*)())gri_scale_umap_loop_PPC;
124     tli->right_edge_func = gr_null;
125     tli->left_edge_func = (void (*)())gri_scale_edge;
126     return (0);
127 }
128 
129 // ========================================================================
130 // main inside loop for PPC scalers
gri_scale_umap_loop_PPC(grs_tmap_loop_info * tli)131 int gri_scale_umap_loop_PPC(grs_tmap_loop_info *tli) {
132     fix u, ul, du;
133     int x;
134     uchar k;
135     fix xl, xr, dx, d;
136     uchar *p_src, *p_dest;
137 
138     xl = fix_cint(tli->left.x);
139     xr = fix_cint(tli->right.x);
140     if (xr <= xl)
141         return TRUE;
142     ul = tli->left.u;
143     dx = tli->right.x - tli->left.x;
144     du = fix_div(tli->right.u - ul, dx);
145     d = fix_ceil(tli->left.x) - tli->left.x;
146     ul += fix_mul(du, d);
147 
148     do {
149         p_src = tli->bm.bits + tli->bm.row * fix_int(tli->left.v);
150         p_dest = grd_bm.bits + (grd_bm.row * tli->y) + xl;
151         switch (tli->bm.hlog) {
152         case GRL_OPAQUE:
153             for (x = xl, u = ul; x < xr; x++) {
154                 *(p_dest++) = p_src[fix_fint(u)]; // gr_fill_upixel(k,x,tli->y);
155                 u += du;
156             }
157             break;
158         case GRL_TRANS:
159             for (x = xl, u = ul; x < xr; x++) {
160                 k = p_src[fix_fint(u)];
161                 if (k != 0)
162                     *p_dest = k; // gr_fill_upixel(k,x,tli->y);
163                 u += du;
164                 p_dest++;
165             }
166             break;
167         case GRL_OPAQUE | GRL_CLUT:
168             for (x = xl, u = ul; x < xr; x++) {
169                 *(p_dest++) = tli->clut[p_src[fix_fint(u)]]; // gr_fill_upixel(tli->clut[k],x,tli->y);
170                 u += du;
171             }
172             break;
173         case GRL_TRANS | GRL_CLUT:
174             for (x = xl, u = ul; x < xr; x++) {
175                 k = p_src[fix_fint(u)];
176                 if (k != 0)
177                     *p_dest = tli->clut[k]; // gr_fill_upixel(tli->clut[k],x,tli->y);
178                 u += du;
179                 p_dest++;
180             }
181             break;
182         case GRL_TRANS | GRL_SOLID:
183             for (x = xl, u = ul; x < xr; x++) {
184                 k = p_src[fix_fint(u)];
185                 if (k != 0)
186                     *p_dest = tli->solid; // gr_fill_upixel((uchar )(tli->clut),x,tli->y);
187                 u += du;
188                 p_dest++;
189             }
190             break;
191         }
192         tli->left.v += tli->left.dv;
193         tli->y++;
194     } while (--(tli->n) > 0);
195 
196     return FALSE; /* tmap OK */
197 }
198