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