cosmetix
[awish.git] / src / polymod.c
blobbcba98e82439f901e3e62ac6df4b770749deca93
1 /*
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation, either version 3 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #include "polymod.h"
17 #include "video.h"
18 #include "gameglobals.h"
21 typedef struct PolyPoint {
22 int next; // -1: none
23 int x;
24 } PolyPoint;
27 static int polyPointPoolSize = 0;
28 static int polyPointPoolPos = 0;
29 static PolyPoint *polyPointPool = NULL;
30 static int polyScans[200]; // index of the first point of each scan; -1: none
31 static int firstX, firstY;
32 static int lastX, lastY;
33 static int firstPoint;
36 void polymodInitialize (void) {
37 for (int f = 0; f < 200; ++f) polyScans[f] = -1;
38 polyPointPool = NULL;
39 polyPointPoolSize = 0;
40 polyPointPoolPos = 0;
41 firstPoint = 1;
45 void polymodDeinitialize (void) {
46 if (polyPointPool != NULL) free(polyPointPool);
47 polyPointPool = NULL;
48 polyPointPoolSize = 0;
49 polyPointPoolPos = 0;
50 firstPoint = 1;
54 static inline int allocPolyPoint (int x, int next) {
55 if (polyPointPoolPos+1 > polyPointPoolSize) {
56 int newsz = polyPointPoolSize+8192;
57 PolyPoint *nn = realloc(polyPointPool, sizeof(PolyPoint)*newsz);
59 if (nn == NULL) fatal("out of memory in polymod");
60 polyPointPool = nn;
61 polyPointPoolSize = newsz;
63 polyPointPool[polyPointPoolPos].x = x;
64 polyPointPool[polyPointPoolPos].next = next;
65 return polyPointPoolPos++;
69 static inline void insertPoint (int x, int y) {
70 if (y >= 0 && y < 200) {
71 int n;
73 //fprintf(stderr, "pt: (%d, %d)\n", x, y);
74 if ((n = polyScans[y]) != -1) {
75 int p;
77 for (p = -1; n != -1 && x > polyPointPool[n].x; p = n, n = polyPointPool[n].next) ;
78 if (n != -1 && x == polyPointPool[n].x) return; // duplicate point
79 if (p == -1) {
80 // this is new first point
81 //fprintf(stderr, " first\n");
82 polyScans[y] = allocPolyPoint(x, n);
83 } else {
84 // insert new point after p; n is the next point
85 //fprintf(stderr, " mid\n");
86 polyPointPool[p].next = allocPolyPoint(x, n);
88 } else {
89 // first
90 //fprintf(stderr, " first\n");
91 polyScans[y] = allocPolyPoint(x, -1);
97 static void lineDDA (int x0, int y0, int x1, int y1) {
98 //fprintf(stderr, "*(%d,%d)-(%d,%d)\n", x0, y0, x1, y1);
99 if (x0 == x1 && y0 == y1) return;
101 if (x0 == x1) {
102 // straight vertical line
103 if (y0 < y1) for (int y = y0; y < y1; ++y) insertPoint(x0, y);
104 else for (int y = y0; y > y1; --y) insertPoint(x0, y);
105 return;
108 if (y0 == y1) {
109 // straight horizontal line
110 insertPoint(x0, y0);
111 return;
113 // draw vertical
114 if (y0 < y1) {
115 double x = x0, dx = (double)(x1-x0)/(double)(y1-y0);
117 for (int y = y0; y < y1; ++y) { insertPoint(x+0.5, y); x += dx; }
118 } else {
119 double x = x0, dx = (double)(x1-x0)/(double)(y0-y1);
121 for (int y = y0; y > y1; --y) { insertPoint(x+0.5, y); x += dx; }
124 void polymodStart (void) {
125 for (int f = 0; f < 200; ++f) polyScans[f] = -1;
126 polyPointPoolPos = 0;
127 firstPoint = 1;
131 void polymodAddPoint (int x, int y) {
132 if (!firstPoint) lineDDA(lastX, lastY, x, y); else { firstX = x; firstY = y; firstPoint = 0; }
133 lastX = x;
134 lastY = y;
138 void polymodEnd (void) {
139 if (!firstPoint) lineDDA(lastX, lastY, firstX, firstY);
143 void polymodFill (SDL_Surface *frame, Uint8 color, Uint8 alpha) {
144 for (int y = 0; y < 200; ++y) {
145 int p = polyScans[y];
147 if (p >= 0) {
148 while (p >= 0 && polyPointPool[p].x < 320) {
149 int n = polyPointPool[p].next/*, ex*/;
151 if (n < 0) {
152 //putPixelA2x(frame, polyPointPool[p].x, y, color, alpha);
153 putPixel2x(frame, polyPointPool[p].x, y, color);
154 break;
156 //fprintf(stderr, "y: %d; x0: %d; x1: %d\n", y, polyPointPool[p].x, polyPointPool[n].x);
157 //ex = polyPointPool[n].x;
158 //for (int x = polyPointPool[p].x; x <= ex; ++x) putPixelA2x(frame, x, y, color, alpha);
159 hline2x(frame, polyPointPool[p].x, y, polyPointPool[n].x-polyPointPool[p].x+1, color);
160 p = polyPointPool[n].next;