dos3d
diff src/scantmpl.h @ 0:f04884489bad
dos3d initial import
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 21 Nov 2011 06:14:01 +0200 |
parents | |
children | 0e781cc43178 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/scantmpl.h Mon Nov 21 06:14:01 2011 +0200 1.3 @@ -0,0 +1,158 @@ 1.4 +/* 1.5 +256-color 3D graphics hack for real-mode DOS. 1.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 1.7 + 1.8 +This program is free software: you can redistribute it and/or modify 1.9 +it under the terms of the GNU General Public License as published by 1.10 +the Free Software Foundation, either version 3 of the License, or 1.11 +(at your option) any later version. 1.12 + 1.13 +This program is distributed in the hope that it will be useful, 1.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 +GNU General Public License for more details. 1.17 + 1.18 +You should have received a copy of the GNU General Public License 1.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 1.20 +*/ 1.21 +static void SCAN_EDGE(struct vertex *v0, struct vertex *v1) 1.22 +{ 1.23 + int i, start, end; 1.24 + float dx, dy, dfdx; 1.25 +#ifdef INTERP_DEPTH 1.26 + float z, dz, dfdz; 1.27 +#endif 1.28 +#ifdef INTERP_ENERGY 1.29 + float e, de, dfde; 1.30 +#endif 1.31 + float x, y; 1.32 + struct vertex *edge; 1.33 + 1.34 + dy = v1->pos.y - v0->pos.y; 1.35 + if(dy < 1e-6 && dy > -1e-6) { 1.36 + return; 1.37 + } 1.38 + 1.39 + dx = v1->pos.x - v0->pos.x; 1.40 + dfdx = dx / dy; 1.41 + 1.42 +#ifdef INTERP_DEPTH 1.43 + assert(fb->zbuf); 1.44 + dz = v1->pos.z - v0->pos.z; 1.45 + dfdz = dz / dy; 1.46 +#endif 1.47 +#ifdef INTERP_ENERGY 1.48 + de = v1->energy - v0->energy; 1.49 + dfde = de / dy; 1.50 +#endif 1.51 + 1.52 + if(dy < 0.0) { 1.53 + struct vertex *tmp = v0; 1.54 + v0 = v1; 1.55 + v1 = tmp; 1.56 + edge = (st->ord == MGL_CCW) ? vright : vleft; 1.57 + } else { 1.58 + edge = (st->ord == MGL_CCW) ? vleft : vright; 1.59 + } 1.60 + 1.61 + start = (int)ROUND(v0->pos.y); 1.62 + end = (int)ROUND(v1->pos.y); 1.63 + 1.64 + x = v0->pos.x; 1.65 +#ifdef INTERP_DEPTH 1.66 + z = v0->pos.z; 1.67 +#endif 1.68 +#ifdef INTERP_ENERGY 1.69 + e = v0->energy; 1.70 +#endif 1.71 + for(i=start; i<end; i++) { 1.72 + edge[i].pos.x = x; 1.73 + x += dfdx; 1.74 + 1.75 + edge[i].cidx = v0->cidx; 1.76 +#ifdef INTERP_DEPTH 1.77 + edge[i].pos.z = z; 1.78 + z += dfdz; 1.79 +#endif 1.80 + 1.81 +#ifdef INTERP_ENERGY 1.82 + edge[i].energy = e; 1.83 + e += dfde; 1.84 +#else 1.85 + edge[i].energy = v0->energy; 1.86 +#endif 1.87 + } 1.88 +} 1.89 + 1.90 +static void SCAN_LINE(int y, unsigned char *sline) 1.91 +{ 1.92 + int i, x0, x1, len, tmp, cidx; 1.93 +#if defined(INTERP_DEPTH) || defined(INTERP_ENERGY) 1.94 + float x, dx; 1.95 +#endif 1.96 +#ifdef INTERP_DEPTH 1.97 + float z, dz, dfdz; 1.98 +#endif 1.99 +#ifdef INTERP_ENERGY 1.100 + float e, de, dfde; 1.101 +#endif 1.102 + struct vertex *left, *right; 1.103 + 1.104 + x0 = (int)ROUND(vleft[y].pos.x); 1.105 + x1 = (int)ROUND(vright[y].pos.x); 1.106 + len = x1 - x0; 1.107 + 1.108 + if(x1 < x0) { 1.109 + if(st->flags & MGL_CULL_FACE) { 1.110 + return; 1.111 + } 1.112 + tmp = x0; 1.113 + x0 = x1; 1.114 + x1 = tmp; 1.115 + len = -len; 1.116 + 1.117 + left = vright; 1.118 + right = vleft; 1.119 + } else { 1.120 + left = vleft; 1.121 + right = vright; 1.122 + } 1.123 + 1.124 + if(x0 < 0) x0 = 0; 1.125 + if(x1 >= fb->width) x1 = fb->width - 1; 1.126 + 1.127 + assert(len >= 0); 1.128 + 1.129 + cidx = left[y].cidx; 1.130 +#if !defined(INTERP_DEPTH) && !defined(INTERP_ENERGY) 1.131 + /* no interpolation at all, just memset the whole scanline */ 1.132 + memset(sline + x0, cidx + left[y].energy * st->col_range, len); 1.133 +#else 1.134 + /* otherwise do a loop and interpolate whatever needs interpolating */ 1.135 + x = left[y].pos.x; 1.136 + dx = right[y].pos.x - x; 1.137 + 1.138 + if(dx < 0.5 && dx > -0.5) { 1.139 + return; 1.140 + } 1.141 + 1.142 +#ifdef INTERP_DEPTH 1.143 + z = left[y].pos.z; 1.144 + dz = right[y].pos.z - z; 1.145 + dfdz = dz / dx; 1.146 +#endif 1.147 +#ifdef INTERP_ENERGY 1.148 + e = left[y].energy; 1.149 + de = right[y].energy - e; 1.150 + dfde = de / dx; 1.151 +#endif 1.152 + 1.153 + for(i=0; i<len; i++) { 1.154 +#ifdef INTERP_ENERGY 1.155 + cidx = left[y].cidx + e * st->col_range; 1.156 + e += dfde; 1.157 +#endif 1.158 + sline[x0 + i] = cidx; 1.159 + } 1.160 +#endif /* flat */ 1.161 +}