dos3d
view src/mglrast.c @ 1:0b7f840afe4a
palette management
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 21 Nov 2011 08:35:58 +0200 |
parents | |
children | 0e781cc43178 |
line source
1 /*
2 256-color 3D graphics hack for real-mode DOS.
3 Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org>
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.
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.
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 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <assert.h>
22 #include "mingl.h"
23 #include "mglimpl.h"
26 static struct vertex *vleft, *vright;
27 static struct framebuffer *fb;
28 static struct state *st;
31 #define SCAN_EDGE scan_edge_flat
32 #define SCAN_LINE scan_line_flat
33 #undef INTERP_DEPTH
34 #undef INTERP_ENERGY
35 #include "scantmpl.h"
36 #undef SCAN_EDGE
37 #undef SCAN_LINE
39 #define SCAN_EDGE scan_edge_z
40 #define SCAN_LINE scan_line_z
41 #define INTERP_DEPTH
42 #undef INTERP_ENERGY
43 #include "scantmpl.h"
44 #undef SCAN_EDGE
45 #undef SCAN_LINE
47 #define SCAN_EDGE scan_edge_e
48 #define SCAN_LINE scan_line_e
49 #undef INTERP_DEPTH
50 #define INTERP_ENERGY
51 #include "scantmpl.h"
52 #undef SCAN_EDGE
53 #undef SCAN_LINE
55 #define SCAN_EDGE scan_edge_ze
56 #define SCAN_LINE scan_line_ze
57 #define INTERP_DEPTH
58 #define INTERP_ENERGY
59 #include "scantmpl.h"
60 #undef SCAN_EDGE
61 #undef SCAN_LINE
63 static void (*scan_edge)(struct vertex*, struct vertex*);
64 static void (*scan_line)(int, unsigned char*);
66 int mgl_rast_init(struct state *state, struct framebuffer *fbuf)
67 {
68 fb = fbuf;
69 st = state;
71 if(!(vleft = malloc(fb->height * sizeof *vleft))) {
72 return -1;
73 }
74 if(!(vright = malloc(fb->height * sizeof *vright))) {
75 free(vleft);
76 return -1;
77 }
79 scan_edge = scan_edge_flat;
80 scan_line = scan_line_flat;
82 return 0;
83 }
85 void mgl_rast_cleanup(void)
86 {
87 free(vleft);
88 free(vright);
89 }
91 void mgl_rast_prepare(void)
92 {
93 static void (*sedge[])(struct vertex*, struct vertex*) = {
94 scan_edge_flat, /* 00 */
95 scan_edge_z, /* 01 */
96 scan_edge_e, /* 10 */
97 scan_edge_ze /* 11 */
98 };
99 static void (*sline[])(int, unsigned char*) = {
100 scan_line_flat, /* 00 */
101 scan_line_z, /* 01 */
102 scan_line_e, /* 10 */
103 scan_line_ze /* 11 */
104 };
105 int bits = 0;
107 if(st->flags & MGL_SMOOTH) {
108 bits |= 2;
109 }
110 if((st->flags & MGL_DEPTH_TEST) && fb->zbuf) {
111 bits |= 1;
112 }
114 scan_edge = sedge[bits];
115 scan_line = sline[bits];
116 }
118 void mgl_draw_point(struct vertex *v)
119 {
120 int x = (int)ROUND(v->pos.x);
121 int y = (int)ROUND(v->pos.y);
123 if(x >= 0 && x < fb->width && y >= 0 && y < fb->height) {
124 int cidx = v->cidx + v->energy * st->col_range;
125 fb->pixels[y * fb->width + x] = cidx;
126 }
127 }
129 void mgl_draw_line(struct vertex *v0, struct vertex *v1)
130 {
131 /* TODO */
132 fprintf(stderr, "draw_line unimplemented\n");
133 abort();
134 }
136 void mgl_draw_poly(struct vertex *v, int numv)
137 {
138 int ybeg, yend, i;
139 unsigned char *sline;
141 ybeg = fb->height;
142 yend = 0;
144 for(i=0; i<numv; i++) {
145 struct vertex *v0 = v + i;
146 struct vertex *v1 = v + (i + 1) % numv;
147 int y = (int)ROUND(v0->pos.y);
149 scan_edge(v0, v1);
151 if(y > yend) yend = y;
152 if(y < ybeg) ybeg = y;
153 }
155 if(ybeg < 0) ybeg = 0;
156 if(yend >= fb->height) yend = fb->height - 1;
158 sline = fb->pixels + ybeg * fb->width;
159 for(i=ybeg; i<yend; i++) {
160 scan_line(i, sline);
161 sline += fb->width;
162 }
163 }