dos3d
diff src/mglrast.c @ 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/mglrast.c Mon Nov 21 06:14:01 2011 +0200 1.3 @@ -0,0 +1,163 @@ 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 +#include <stdio.h> 1.22 +#include <stdlib.h> 1.23 +#include <string.h> 1.24 +#include <assert.h> 1.25 +#include "mingl.h" 1.26 +#include "mglimpl.h" 1.27 + 1.28 + 1.29 +static struct vertex *vleft, *vright; 1.30 +static struct framebuffer *fb; 1.31 +static struct state *st; 1.32 + 1.33 + 1.34 +#define SCAN_EDGE scan_edge_flat 1.35 +#define SCAN_LINE scan_line_flat 1.36 +#undef INTERP_DEPTH 1.37 +#undef INTERP_ENERGY 1.38 +#include "scantmpl.h" 1.39 +#undef SCAN_EDGE 1.40 +#undef SCAN_LINE 1.41 + 1.42 +#define SCAN_EDGE scan_edge_z 1.43 +#define SCAN_LINE scan_line_z 1.44 +#define INTERP_DEPTH 1.45 +#undef INTERP_ENERGY 1.46 +#include "scantmpl.h" 1.47 +#undef SCAN_EDGE 1.48 +#undef SCAN_LINE 1.49 + 1.50 +#define SCAN_EDGE scan_edge_e 1.51 +#define SCAN_LINE scan_line_e 1.52 +#undef INTERP_DEPTH 1.53 +#define INTERP_ENERGY 1.54 +#include "scantmpl.h" 1.55 +#undef SCAN_EDGE 1.56 +#undef SCAN_LINE 1.57 + 1.58 +#define SCAN_EDGE scan_edge_ze 1.59 +#define SCAN_LINE scan_line_ze 1.60 +#define INTERP_DEPTH 1.61 +#define INTERP_ENERGY 1.62 +#include "scantmpl.h" 1.63 +#undef SCAN_EDGE 1.64 +#undef SCAN_LINE 1.65 + 1.66 +static void (*scan_edge)(struct vertex*, struct vertex*); 1.67 +static void (*scan_line)(int, unsigned char*); 1.68 + 1.69 +int mgl_rast_init(struct state *state, struct framebuffer *fbuf) 1.70 +{ 1.71 + fb = fbuf; 1.72 + st = state; 1.73 + 1.74 + if(!(vleft = malloc(fb->height * sizeof *vleft))) { 1.75 + return -1; 1.76 + } 1.77 + if(!(vright = malloc(fb->height * sizeof *vright))) { 1.78 + free(vleft); 1.79 + return -1; 1.80 + } 1.81 + 1.82 + scan_edge = scan_edge_flat; 1.83 + scan_line = scan_line_flat; 1.84 + 1.85 + return 0; 1.86 +} 1.87 + 1.88 +void mgl_rast_cleanup(void) 1.89 +{ 1.90 + free(vleft); 1.91 + free(vright); 1.92 +} 1.93 + 1.94 +void mgl_rast_prepare(void) 1.95 +{ 1.96 + static void (*sedge[])(struct vertex*, struct vertex*) = { 1.97 + scan_edge_flat, /* 00 */ 1.98 + scan_edge_z, /* 01 */ 1.99 + scan_edge_e, /* 10 */ 1.100 + scan_edge_ze /* 11 */ 1.101 + }; 1.102 + static void (*sline[])(int, unsigned char*) = { 1.103 + scan_line_flat, /* 00 */ 1.104 + scan_line_z, /* 01 */ 1.105 + scan_line_e, /* 10 */ 1.106 + scan_line_ze /* 11 */ 1.107 + }; 1.108 + int bits = 0; 1.109 + 1.110 + if(st->flags & MGL_SMOOTH) { 1.111 + bits |= 2; 1.112 + } 1.113 + if((st->flags & MGL_DEPTH_TEST) && fb->zbuf) { 1.114 + bits |= 1; 1.115 + } 1.116 + 1.117 + scan_edge = sedge[bits]; 1.118 + scan_line = sline[bits]; 1.119 +} 1.120 + 1.121 +void mgl_draw_point(struct vertex *v) 1.122 +{ 1.123 + int x = (int)ROUND(v->pos.x); 1.124 + int y = (int)ROUND(v->pos.y); 1.125 + 1.126 + if(x >= 0 && x < fb->width && y >= 0 && y < fb->height) { 1.127 + int cidx = v->cidx + v->energy * st->col_range; 1.128 + fb->pixels[y * fb->width + x] = cidx; 1.129 + } 1.130 +} 1.131 + 1.132 +void mgl_draw_line(struct vertex *v0, struct vertex *v1) 1.133 +{ 1.134 + /* TODO */ 1.135 + fprintf(stderr, "draw_line unimplemented\n"); 1.136 + abort(); 1.137 +} 1.138 + 1.139 +void mgl_draw_poly(struct vertex *v, int numv) 1.140 +{ 1.141 + int ybeg, yend, i; 1.142 + unsigned char *sline; 1.143 + 1.144 + ybeg = fb->height; 1.145 + yend = 0; 1.146 + 1.147 + for(i=0; i<numv; i++) { 1.148 + struct vertex *v0 = v + i; 1.149 + struct vertex *v1 = v + (i + 1) % numv; 1.150 + int y = (int)ROUND(v0->pos.y); 1.151 + 1.152 + scan_edge(v0, v1); 1.153 + 1.154 + if(y > yend) yend = y; 1.155 + if(y < ybeg) ybeg = y; 1.156 + } 1.157 + 1.158 + if(ybeg < 0) ybeg = 0; 1.159 + if(yend >= fb->height) yend = fb->height - 1; 1.160 + 1.161 + sline = fb->pixels + ybeg * fb->width; 1.162 + for(i=ybeg; i<yend; i++) { 1.163 + scan_line(i, sline); 1.164 + sline += fb->width; 1.165 + } 1.166 +}