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/polyint.h $ 21 * $Revision: 1.8 $ 22 * $Author: kevin $ 23 * $Date: 1994/07/18 17:08:25 $ 24 * 25 * Polygon scanning internal macros. 26 * 27 */ 28 29 #ifndef __POLYINT_H 30 #define __POLYINT_H 31 32 #include "fix.h" 33 #include "grs.h" 34 #include "plytyp.h" 35 36 #define poly_find_y_extrema(_y_min,_y_max,_p_left,_vpl,_n) \ 37 do { \ 38 grs_vertex **pvp; \ 39 int __y; \ 40 _y_min = fix_cint(_vpl[0]->y); \ 41 _y_max = fix_cint(_vpl[0]->y); \ 42 _p_left = _vpl; \ 43 for (pvp=_vpl+1; pvp<_vpl+_n; ++pvp) { \ 44 __y=fix_cint((*pvp)->y); \ 45 if (__y < _y_min) { \ 46 _y_min = __y; \ 47 _p_left = pvp; \ 48 } \ 49 if (__y > _y_max) \ 50 _y_max = __y; \ 51 } \ 52 if (_y_min == _y_max) return; \ 53 } while(0) 54 /* 55 #define poly_find_yw_extrema(_y_min,_y_max,_w_min,_w_max,_p_left,_vpl,_n) \ 56 do { \ 57 grs_vertex **pvp; \ 58 int y; \ 59 _p_left = _vpl; \ 60 _y_min = fix_cint(_vpl[0]->y); \ 61 _y_max = fix_cint(_vpl[0]->y); \ 62 _w_min = _vpl[0]->w; \ 63 _w_max = _vpl[0]->w; \ 64 for (pvp=_vpl+1; pvp<_vpl+_n; ++pvp) { \ 65 y=fix_cint((*pvp)->y); \ 66 if (y < _y_min) { \ 67 _y_min = y; \ 68 _w_min = (*pvp)->w; \ 69 _p_left = pvp; \ 70 } \ 71 if (y > _y_max) { \ 72 _y_max = y; \ 73 _w_max = (*pvp)->w; \ 74 } \ 75 } \ 76 if (_y_min == _y_max) return; \ 77 } while(0) 78 */ 79 #define poly_find_x_extrema(_x_min,_x_max,_p_top,_vpl,_n) \ 80 do { \ 81 grs_vertex **pvp; \ 82 int __x; \ 83 _x_min = fix_cint(_vpl[0]->x); \ 84 _x_max = fix_cint(_vpl[0]->x); \ 85 _p_top = _vpl; \ 86 for (pvp=_vpl+1; pvp<_vpl+_n; ++pvp) { \ 87 __x=fix_cint((*pvp)->x); \ 88 if (__x < _x_min) { \ 89 _x_min = __x; \ 90 _p_top = pvp; \ 91 } \ 92 if (__x > _x_max) \ 93 _x_max = __x; \ 94 } \ 95 if (_x_min == _x_max) return; \ 96 } while(0) 97 98 #define poly_find_xw_extrema(_x_min,_x_max,_w_min,_w_max,_p_top,_vpl,_n) \ 99 do { \ 100 grs_vertex **pvp; \ 101 int __x; \ 102 _x_min = fix_cint(_vpl[0]->x); \ 103 _x_max = fix_cint(_vpl[0]->x); \ 104 _w_min = _vpl[0]->w; \ 105 _w_max = _vpl[0]->w; \ 106 _p_top = _vpl; \ 107 for (pvp=_vpl+1; pvp<_vpl+_n; ++pvp) { \ 108 __x=fix_cint((*pvp)->x); \ 109 if (__x < _x_min) { \ 110 _x_min = __x; \ 111 _w_min = (*pvp)->w; \ 112 _p_top = pvp; \ 113 } \ 114 if (__x > _x_max) { \ 115 _w_max = (*pvp)->w; \ 116 _x_max = __x; \ 117 } \ 118 } \ 119 if (_x_min == _x_max) return; \ 120 } while(0) 121 122 #define poly_find_x_extrema_retval(_x_min,_x_max,_p_top,_vpl,_n,_retval) \ 123 do { \ 124 grs_vertex **pvp; \ 125 int __x; \ 126 _x_min = fix_cint(_vpl[0]->x); \ 127 _x_max = fix_cint(_vpl[0]->x); \ 128 _p_top = _vpl; \ 129 for (pvp=_vpl+1; pvp<_vpl+_n; ++pvp) { \ 130 __x=fix_cint((*pvp)->x); \ 131 if (__x < _x_min) { \ 132 _x_min = __x; \ 133 _p_top = pvp; \ 134 } \ 135 if (__x > _x_max) \ 136 _x_max = __x; \ 137 } \ 138 if (_x_min == _x_max) return _retval; \ 139 } while(0) 140 141 142 #define poly_do_left_edge(_p_left,_prev,_y_left,_y_prev,_y,_vpl,_n) \ 143 do { \ 144 _y_left = (*_p_left)->y; \ 145 do { \ 146 if (fix_cint(_y_left)==_y) _prev=*_p_left;\ 147 if (--_p_left < _vpl) \ 148 _p_left=_vpl+_n-1; \ 149 _y_prev=_y_left; \ 150 _y_left=(*_p_left)->y; \ 151 } while (fix_cint(_y_left)<=_y); \ 152 } while (0) 153 154 #define poly_do_top_edge(_p_top,_prev,_x_top,_x_prev,_x,_vpl,_n) \ 155 do { \ 156 _x_top = (*_p_top)->x; \ 157 do { \ 158 if (fix_cint(_x_top)==_x) _prev=*_p_top;\ 159 if (++_p_top >= _vpl+n) \ 160 _p_top=_vpl; \ 161 _x_prev=_x_top; \ 162 _x_top=(*_p_top)->x; \ 163 } while (fix_cint(_x_top)<=_x); \ 164 } while (0) 165 166 #define poly_do_right_edge(_p_right,_prev,_y_right,_y_prev,_y,_vpl,_n) \ 167 do { \ 168 _y_right = (*_p_right)->y; \ 169 do { \ 170 if (fix_cint(_y_right)==_y) _prev=*_p_right; \ 171 if (++_p_right >= _vpl+_n) \ 172 _p_right=_vpl; \ 173 _y_prev=_y_right; \ 174 _y_right=(*_p_right)->y; \ 175 } while (fix_cint(_y_right)<=_y); \ 176 } while (0) 177 178 #define poly_do_bot_edge(_p_bot,_prev,_x_bot,_x_prev,_x,_vpl,_n) \ 179 do { \ 180 _x_bot = (*_p_bot)->x; \ 181 do { \ 182 if (fix_cint(_x_bot)==_x) _prev=*_p_bot;\ 183 if (--_p_bot < _vpl) \ 184 _p_bot=_vpl+_n-1; \ 185 _x_prev=_x_bot; \ 186 _x_bot=(*_p_bot)->x; \ 187 } while (fix_cint(_x_bot)<=_x); \ 188 } while (0) 189 190 #define poly_do_x(p_next,_prev,y_next,_y_prev,_d,x0,dx) \ 191 do { \ 192 _d = y_next-_y_prev; \ 193 x0 = _prev->x; \ 194 dx = fix_div((*p_next)->x-x0, _d); \ 195 x0 += fix_mul(dx,fix_ceil(_y_prev)-_y_prev); \ 196 } while (0) 197 198 #define poly_do_y_bot(p_next,_prev,x_next,_x_prev,_d,y0,dy) \ 199 do { \ 200 _d = x_next-_x_prev; \ 201 y0 = _prev->y; \ 202 dy = fix_div((*p_next)->y-y0, _d); \ 203 y0 += fix_mul(dy,fix_ceil(_x_prev)-_x_prev); \ 204 if (dy>0) y0++; \ 205 } while (0) 206 207 #define poly_do_y_top(p_next,_prev,x_next,_x_prev,_d,y0,dy) \ 208 do { \ 209 _d = x_next-_x_prev; \ 210 y0 = _prev->y; \ 211 dy = fix_div((*p_next)->y-y0, _d); \ 212 y0 += fix_mul(dy,fix_ceil(_x_prev)-_x_prev); \ 213 if (dy>0) y0++; \ 214 } while (0) 215 216 #define poly_do_uv(p_next,_prev,_d,u0,du,v0,dv) \ 217 do { \ 218 u0 = (_prev->u); \ 219 du = fix_div((*p_next)->u-u0, _d); \ 220 u0 += fix_mul(du,fix_ceil(_prev->y)-_prev->y);\ 221 v0 = (_prev->v); \ 222 dv = fix_div((*p_next)->v-v0, _d); \ 223 v0 += fix_mul(dv,fix_ceil(_prev->y)-_prev->y);\ 224 } while (0) 225 226 #define poly_do_rgb(p_next,_prev,_d,r0,dr,g0,dg,b0,db) \ 227 do { \ 228 r0 = (_prev->u); \ 229 dr = fix_div((*p_next)->u-r0, _d); \ 230 r0 += fix_mul(dr,fix_ceil(_prev->y)-_prev->y);\ 231 g0 = (_prev->v); \ 232 dg = fix_div((*p_next)->v-g0, _d); \ 233 g0 += fix_mul(dg,fix_ceil(_prev->y)-_prev->y);\ 234 b0 = (_prev->w); \ 235 db = fix_div((*p_next)->w-b0, _d); \ 236 b0 += fix_mul(db,fix_ceil(_prev->y)-_prev->y);\ 237 } while (0) 238 239 #define poly_do_uvw(p_next,_prev,_d,u0,du,v0,dv,w0,dw) \ 240 do { \ 241 w0 = _prev->w; \ 242 dw = fix_div((*p_next)->w-w0, _d); \ 243 u0 = fix_mul(_prev->u,w0); \ 244 du = fix_div(fix_mul((*p_next)->u,(*p_next)->w) - u0, _d); \ 245 u0 += fix_mul(du,fix_ceil(_prev->y)-_prev->y); \ 246 v0 = fix_mul(_prev->v,w0); \ 247 dv = fix_div(fix_mul((*p_next)->v,(*p_next)->w) - v0, _d); \ 248 v0 += fix_mul(dv,fix_ceil(_prev->y)-_prev->y); \ 249 } while (0) 250 251 #define poly_do_i(p_next,_prev,_d,i0,di) \ 252 do { \ 253 i0 = _prev->i; \ 254 di = fix_div((*p_next)->i-i0, _d); \ 255 i0 += fix_mul(di,fix_ceil(_prev->y)-_prev->y);\ 256 } while (0) 257 258 #define poly_do_iw(p_next,_prev,_d,i0,di,w0) \ 259 do { \ 260 i0 = fix_mul(_prev->i,w0); \ 261 di = fix_div(fix_mul((*p_next)->i,(*p_next)->w) - i0, _d);\ 262 i0 += fix_mul(di,fix_ceil(_prev->y)-_prev->y);\ 263 } while (0) 264 265 #define poly_do_uv_vscan(p_next,_prev,_d,u0,du,v0,dv) \ 266 do { \ 267 u0 = (_prev->u); \ 268 du = fix_div((*p_next)->u-u0, _d); \ 269 u0 += fix_mul(du,fix_ceil(_prev->x)-_prev->x);\ 270 v0 = (_prev->v); \ 271 dv = fix_div((*p_next)->v-v0, _d); \ 272 v0 += fix_mul(dv,fix_ceil(_prev->x)-_prev->x);\ 273 } while (0) 274 275 #define poly_do_rgb_vscan(p_next,_prev,_d,r0,dr,g0,dg,b0,db) \ 276 do { \ 277 r0 = (_prev->u); \ 278 dr = fix_div((*p_next)->u-r0, _d); \ 279 r0 += fix_mul(dr,fix_ceil(_prev->x)-_prev->x);\ 280 g0 = (_prev->v); \ 281 dg = fix_div((*p_next)->v-g0, _d); \ 282 g0 += fix_mul(dg,fix_ceil(_prev->x)-_prev->x);\ 283 b0 = (_prev->w); \ 284 db = fix_div((*p_next)->w-b0, _d); \ 285 b0 += fix_mul(db,fix_ceil(_prev->x)-_prev->x);\ 286 } while (0) 287 288 #define poly_do_uvw_vscan(p_next,_prev,_d,u0,du,v0,dv,w0,dw) \ 289 do { \ 290 w0 = _prev->w; \ 291 dw = fix_div((*p_next)->w-w0, _d); \ 292 u0 = fix_mul(_prev->u,w0); \ 293 du = fix_div(fix_mul((*p_next)->u,(*p_next)->w) - u0, _d); \ 294 u0 += fix_mul(du,fix_ceil(_prev->x)-_prev->x); \ 295 v0 = fix_mul(_prev->v,w0); \ 296 dv = fix_div(fix_mul((*p_next)->v,(*p_next)->w) - v0, _d); \ 297 v0 += fix_mul(dv,fix_ceil(_prev->x)-_prev->x); \ 298 } while (0) 299 300 #define poly_do_i_vscan(p_next,_prev,_d,i0,di) \ 301 do { \ 302 i0 = _prev->i; \ 303 di = fix_div((*p_next)->i-i0, _d); \ 304 i0 += fix_mul(di,fix_ceil(_prev->x)-_prev->x);\ 305 } while (0) 306 307 #define poly_do_iw_vscan(p_next,_prev,_d,i0,di,w0) \ 308 do { \ 309 i0 = fix_mul(_prev->i,w0); \ 310 di = fix_div(fix_mul((*p_next)->i,(*p_next)->w) - i0, _d);\ 311 i0 += fix_mul(di,fix_ceil(_prev->x)-_prev->x);\ 312 } while (0) 313 #endif /* !__POLYINT_H */ 314 315 316