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/>.
18 #include "gameglobals.h"
21 typedef struct 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;
39 polyPointPoolSize
= 0;
45 void polymodDeinitialize (void) {
46 if (polyPointPool
!= NULL
) free(polyPointPool
);
48 polyPointPoolSize
= 0;
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");
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) {
73 //fprintf(stderr, "pt: (%d, %d)\n", x, y);
74 if ((n
= polyScans
[y
]) != -1) {
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
80 // this is new first point
81 //fprintf(stderr, " first\n");
82 polyScans
[y
] = allocPolyPoint(x
, n
);
84 // insert new point after p; n is the next point
85 //fprintf(stderr, " mid\n");
86 polyPointPool
[p
].next
= allocPolyPoint(x
, n
);
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;
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
);
109 // straight horizontal line
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
; }
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;
131 void polymodAddPoint (int x
, int y
) {
132 if (!firstPoint
) lineDDA(lastX
, lastY
, x
, y
); else { firstX
= x
; firstY
= y
; firstPoint
= 0; }
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
];
148 while (p
>= 0 && polyPointPool
[p
].x
< 320) {
149 int n
= polyPointPool
[p
].next
/*, ex*/;
152 //putPixelA2x(frame, polyPointPool[p].x, y, color, alpha);
153 putPixel2x(frame
, polyPointPool
[p
].x
, y
, color
);
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
;