graphics 1.0.0b1 → 1.0.0b4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +30 -0
- data/Manifest.txt +39 -7
- data/README.rdoc +48 -4
- data/Rakefile +8 -2
- data/examples/boid.rb +9 -18
- data/examples/bounce.rb +15 -23
- data/examples/canvas.rb +75 -0
- data/examples/collision.rb +6 -6
- data/examples/demo.rb +5 -7
- data/examples/editor.rb +12 -9
- data/examples/fluid.rb +2 -3
- data/examples/fluid2.rb +1 -1
- data/examples/{lito2.rb → gol.rb} +0 -0
- data/examples/{zenspider4.rb → gol2.rb} +0 -0
- data/examples/logo.rb +4 -7
- data/examples/maze.rb +136 -0
- data/examples/tank.rb +10 -11
- data/examples/tank2.rb +12 -17
- data/examples/targeting.rb +1 -1
- data/examples/vants.rb +1 -1
- data/examples/walker.rb +3 -12
- data/examples/walker2.rb +197 -0
- data/examples/zombies.rb +31 -35
- data/ext/sdl/extconf.rb +31 -0
- data/ext/sdl/sdl.c +1067 -0
- data/ext/sdl/sge/INSTALL +72 -0
- data/ext/sdl/sge/LICENSE +504 -0
- data/ext/sdl/sge/Makefile +83 -0
- data/ext/sdl/sge/Makefile.conf +63 -0
- data/ext/sdl/sge/README +219 -0
- data/ext/sdl/sge/Todo +7 -0
- data/ext/sdl/sge/WhatsNew +224 -0
- data/ext/sdl/sge/sge.h +31 -0
- data/ext/sdl/sge/sge_blib.cpp +1939 -0
- data/ext/sdl/sge/sge_blib.h +68 -0
- data/ext/sdl/sge/sge_bm_text.cpp +451 -0
- data/ext/sdl/sge/sge_bm_text.h +71 -0
- data/ext/sdl/sge/sge_collision.cpp +388 -0
- data/ext/sdl/sge/sge_collision.h +54 -0
- data/ext/sdl/sge/sge_config.h +6 -0
- data/ext/sdl/sge/sge_internal.h +152 -0
- data/ext/sdl/sge/sge_misc.cpp +92 -0
- data/ext/sdl/sge/sge_misc.h +37 -0
- data/ext/sdl/sge/sge_primitives.cpp +2516 -0
- data/ext/sdl/sge/sge_primitives.h +111 -0
- data/ext/sdl/sge/sge_rotation.cpp +683 -0
- data/ext/sdl/sge/sge_rotation.h +46 -0
- data/ext/sdl/sge/sge_shape.cpp +762 -0
- data/ext/sdl/sge/sge_shape.h +365 -0
- data/ext/sdl/sge/sge_surface.cpp +1090 -0
- data/ext/sdl/sge/sge_surface.h +100 -0
- data/ext/sdl/sge/sge_textpp.cpp +785 -0
- data/ext/sdl/sge/sge_textpp.h +270 -0
- data/ext/sdl/sge/sge_tt_text.cpp +1456 -0
- data/ext/sdl/sge/sge_tt_text.h +114 -0
- data/graphics_setup.sh +26 -0
- data/lib/graphics.rb +1 -1
- data/lib/graphics/body.rb +50 -3
- data/lib/graphics/extensions.rb +13 -7
- data/lib/graphics/simulation.rb +126 -46
- data/test/test_graphics.rb +52 -12
- data/test/test_sdl.rb +1 -0
- metadata +54 -23
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
- data/examples/lito.rb +0 -108
- data/examples/zenspider1.rb +0 -93
- data/examples/zenspider2.rb +0 -123
- data/examples/zenspider3.rb +0 -104
- data/rubysdl_setup.sh +0 -34
data/ext/sdl/sge/sge.h
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
/*
|
2
|
+
* SDL Graphics Extension
|
3
|
+
*
|
4
|
+
* Started 990815
|
5
|
+
*
|
6
|
+
* License: LGPL v2+ (see the file LICENSE)
|
7
|
+
* (c)1999-2003 Anders Lindstr�m
|
8
|
+
*/
|
9
|
+
|
10
|
+
/*********************************************************************
|
11
|
+
* This library is free software; you can redistribute it and/or *
|
12
|
+
* modify it under the terms of the GNU Library General Public *
|
13
|
+
* License as published by the Free Software Foundation; either *
|
14
|
+
* version 2 of the License, or (at your option) any later version. *
|
15
|
+
*********************************************************************/
|
16
|
+
|
17
|
+
#ifndef sge_H
|
18
|
+
#define sge_H
|
19
|
+
|
20
|
+
#include "sge_surface.h"
|
21
|
+
#include "sge_primitives.h"
|
22
|
+
#include "sge_misc.h"
|
23
|
+
#include "sge_tt_text.h"
|
24
|
+
#include "sge_bm_text.h"
|
25
|
+
#include "sge_textpp.h"
|
26
|
+
#include "sge_blib.h"
|
27
|
+
#include "sge_shape.h"
|
28
|
+
#include "sge_collision.h"
|
29
|
+
#include "sge_rotation.h"
|
30
|
+
|
31
|
+
#endif /* sge_H */
|
@@ -0,0 +1,1939 @@
|
|
1
|
+
/*
|
2
|
+
* SDL Graphics Extension
|
3
|
+
* Triangles of every sort
|
4
|
+
*
|
5
|
+
* Started 000428
|
6
|
+
*
|
7
|
+
* License: LGPL v2+ (see the file LICENSE)
|
8
|
+
* (c)2000-2003 Anders Lindstr�m & Johan E. Thelin
|
9
|
+
*/
|
10
|
+
|
11
|
+
/*********************************************************************
|
12
|
+
* This library is free software; you can redistribute it and/or *
|
13
|
+
* modify it under the terms of the GNU Library General Public *
|
14
|
+
* License as published by the Free Software Foundation; either *
|
15
|
+
* version 2 of the License, or (at your option) any later version. *
|
16
|
+
*********************************************************************/
|
17
|
+
|
18
|
+
/*
|
19
|
+
* Written with some help from Johan E. Thelin.
|
20
|
+
*/
|
21
|
+
|
22
|
+
#include "SDL.h"
|
23
|
+
#include "sge_surface.h"
|
24
|
+
#include "sge_primitives.h"
|
25
|
+
#include "sge_blib.h"
|
26
|
+
|
27
|
+
#define SWAP(x,y,temp) temp=x;x=y;y=temp
|
28
|
+
|
29
|
+
/* Globals used for sge_Update/sge_Lock (defined in sge_surface) */
|
30
|
+
extern Uint8 _sge_update;
|
31
|
+
extern Uint8 _sge_lock;
|
32
|
+
extern Uint8 _sge_alpha_hack;
|
33
|
+
|
34
|
+
/* We need some internal functions */
|
35
|
+
extern void _Line(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
|
36
|
+
extern void _LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha);
|
37
|
+
extern void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color);
|
38
|
+
extern void _HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha);
|
39
|
+
extern void callback_alpha_hack(SDL_Surface *surf, Sint16 x, Sint16 y, Uint32 color);
|
40
|
+
extern void _AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha);
|
41
|
+
extern void _AAmcLineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2, Uint8 alpha);
|
42
|
+
|
43
|
+
/* Macro to inline RGB mapping */
|
44
|
+
#define MapRGB(format, r, g, b)\
|
45
|
+
(r >> format->Rloss) << format->Rshift\
|
46
|
+
| (g >> format->Gloss) << format->Gshift\
|
47
|
+
| (b >> format->Bloss) << format->Bshift
|
48
|
+
|
49
|
+
|
50
|
+
//==================================================================================
|
51
|
+
// Draws a horisontal line, fading the colors
|
52
|
+
//==================================================================================
|
53
|
+
void _FadedLine(SDL_Surface *dest,Sint16 x1,Sint16 x2,Sint16 y,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2)
|
54
|
+
{
|
55
|
+
Sint16 x;
|
56
|
+
Uint8 t;
|
57
|
+
|
58
|
+
/* Fix coords */
|
59
|
+
if ( x1 > x2 ) {
|
60
|
+
SWAP(x1,x2,x);
|
61
|
+
SWAP(r1,r2,t);
|
62
|
+
SWAP(g1,g2,t);
|
63
|
+
SWAP(b1,b2,t);
|
64
|
+
}
|
65
|
+
|
66
|
+
/* We use fixedpoint math */
|
67
|
+
Sint32 R = r1<<16;
|
68
|
+
Sint32 G = g1<<16;
|
69
|
+
Sint32 B = b1<<16;
|
70
|
+
|
71
|
+
/* Color step value */
|
72
|
+
Sint32 rstep = Sint32((r2-r1)<<16) / Sint32(x2-x1+1);
|
73
|
+
Sint32 gstep = Sint32((g2-g1)<<16) / Sint32(x2-x1+1);
|
74
|
+
Sint32 bstep = Sint32((b2-b1)<<16) / Sint32(x2-x1+1);
|
75
|
+
|
76
|
+
|
77
|
+
/* Clipping */
|
78
|
+
if(x2<sge_clip_xmin(dest) || x1>sge_clip_xmax(dest) || y<sge_clip_ymin(dest) || y>sge_clip_ymax(dest))
|
79
|
+
return;
|
80
|
+
if (x1 < sge_clip_xmin(dest)){
|
81
|
+
/* Update start colors */
|
82
|
+
R += (sge_clip_xmin(dest)-x1)*rstep;
|
83
|
+
G += (sge_clip_xmin(dest)-x1)*gstep;
|
84
|
+
B += (sge_clip_xmin(dest)-x1)*bstep;
|
85
|
+
x1 = sge_clip_xmin(dest);
|
86
|
+
}
|
87
|
+
if (x2 > sge_clip_xmax(dest))
|
88
|
+
x2 = sge_clip_xmax(dest);
|
89
|
+
|
90
|
+
|
91
|
+
switch (dest->format->BytesPerPixel) {
|
92
|
+
case 1: { /* Assuming 8-bpp */
|
93
|
+
Uint8 *pixel;
|
94
|
+
Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch;
|
95
|
+
|
96
|
+
for (x = x1; x <= x2; x++){
|
97
|
+
pixel = row + x;
|
98
|
+
|
99
|
+
*pixel = SDL_MapRGB( dest->format, R>>16, G>>16, B>>16 );
|
100
|
+
|
101
|
+
R += rstep;
|
102
|
+
G += gstep;
|
103
|
+
B += bstep;
|
104
|
+
}
|
105
|
+
}
|
106
|
+
break;
|
107
|
+
|
108
|
+
case 2: { /* Probably 15-bpp or 16-bpp */
|
109
|
+
Uint16 *pixel;
|
110
|
+
Uint16 *row = (Uint16 *)dest->pixels + y*dest->pitch/2;
|
111
|
+
|
112
|
+
for (x = x1; x <= x2; x++){
|
113
|
+
pixel = row + x;
|
114
|
+
|
115
|
+
*pixel = MapRGB( dest->format, R>>16, G>>16, B>>16 );
|
116
|
+
|
117
|
+
R += rstep;
|
118
|
+
G += gstep;
|
119
|
+
B += bstep;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
break;
|
123
|
+
|
124
|
+
case 3: { /* Slow 24-bpp mode, usually not used */
|
125
|
+
Uint8 *pixel;
|
126
|
+
Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch;
|
127
|
+
|
128
|
+
Uint8 rshift8=dest->format->Rshift/8;
|
129
|
+
Uint8 gshift8=dest->format->Gshift/8;
|
130
|
+
Uint8 bshift8=dest->format->Bshift/8;
|
131
|
+
|
132
|
+
for (x = x1; x <= x2; x++){
|
133
|
+
pixel = row + x*3;
|
134
|
+
|
135
|
+
*(pixel+rshift8) = R>>16;
|
136
|
+
*(pixel+gshift8) = G>>16;
|
137
|
+
*(pixel+bshift8) = B>>16;
|
138
|
+
|
139
|
+
R += rstep;
|
140
|
+
G += gstep;
|
141
|
+
B += bstep;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
break;
|
145
|
+
|
146
|
+
case 4: { /* Probably 32-bpp */
|
147
|
+
Uint32 *pixel;
|
148
|
+
Uint32 *row = (Uint32 *)dest->pixels + y*dest->pitch/4;
|
149
|
+
|
150
|
+
for (x = x1; x <= x2; x++){
|
151
|
+
pixel = row + x;
|
152
|
+
|
153
|
+
*pixel = MapRGB( dest->format, R>>16, G>>16, B>>16 );
|
154
|
+
|
155
|
+
R += rstep;
|
156
|
+
G += gstep;
|
157
|
+
B += bstep;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
break;
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
void sge_FadedLine(SDL_Surface *dest,Sint16 x1,Sint16 x2,Sint16 y,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2)
|
165
|
+
{
|
166
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
167
|
+
if ( SDL_LockSurface(dest) < 0 )
|
168
|
+
return;
|
169
|
+
|
170
|
+
_FadedLine(dest,x1,x2,y,r1,g1,b1,r2,g2,b2);
|
171
|
+
|
172
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
173
|
+
SDL_UnlockSurface(dest);
|
174
|
+
|
175
|
+
if(_sge_update!=1){return;}
|
176
|
+
if ( x1 > x2 )
|
177
|
+
sge_UpdateRect(dest, x1, y, x1-x2+1, 1);
|
178
|
+
else
|
179
|
+
sge_UpdateRect(dest, x1, y, x2-x1+1, 1);
|
180
|
+
}
|
181
|
+
|
182
|
+
|
183
|
+
//==================================================================================
|
184
|
+
// Draws a horisontal, textured line
|
185
|
+
//==================================================================================
|
186
|
+
void _TexturedLine(SDL_Surface *dest,Sint16 x1,Sint16 x2,Sint16 y,SDL_Surface *source,Sint16 sx1,Sint16 sy1,Sint16 sx2,Sint16 sy2)
|
187
|
+
{
|
188
|
+
Sint16 x;
|
189
|
+
|
190
|
+
/* Fix coords */
|
191
|
+
if ( x1 > x2 ) {
|
192
|
+
SWAP(x1,x2,x);
|
193
|
+
SWAP(sx1,sx2,x);
|
194
|
+
SWAP(sy1,sy2,x);
|
195
|
+
}
|
196
|
+
|
197
|
+
/* Fixed point texture starting coords */
|
198
|
+
Sint32 srcx = sx1<<16;
|
199
|
+
Sint32 srcy = sy1<<16;
|
200
|
+
|
201
|
+
/* Texture coords stepping value */
|
202
|
+
Sint32 xstep = Sint32((sx2-sx1)<<16) / Sint32(x2-x1+1);
|
203
|
+
Sint32 ystep = Sint32((sy2-sy1)<<16) / Sint32(x2-x1+1);
|
204
|
+
|
205
|
+
|
206
|
+
/* Clipping */
|
207
|
+
if(x2<sge_clip_xmin(dest) || x1>sge_clip_xmax(dest) || y<sge_clip_ymin(dest) || y>sge_clip_ymax(dest))
|
208
|
+
return;
|
209
|
+
if (x1 < sge_clip_xmin(dest)){
|
210
|
+
/* Fix texture starting coord */
|
211
|
+
srcx += (sge_clip_xmin(dest)-x1)*xstep;
|
212
|
+
srcy += (sge_clip_xmin(dest)-x1)*ystep;
|
213
|
+
x1 = sge_clip_xmin(dest);
|
214
|
+
}
|
215
|
+
if (x2 > sge_clip_xmax(dest))
|
216
|
+
x2 = sge_clip_xmax(dest);
|
217
|
+
|
218
|
+
|
219
|
+
if(dest->format->BytesPerPixel == source->format->BytesPerPixel){
|
220
|
+
/* Fast mode. Just copy the pixel */
|
221
|
+
|
222
|
+
switch (dest->format->BytesPerPixel) {
|
223
|
+
case 1: { /* Assuming 8-bpp */
|
224
|
+
Uint8 *pixel;
|
225
|
+
Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch;
|
226
|
+
|
227
|
+
for (x = x1; x <= x2; x++){
|
228
|
+
pixel = row + x;
|
229
|
+
|
230
|
+
*pixel = *((Uint8 *)source->pixels + (srcy>>16)*source->pitch + (srcx>>16));
|
231
|
+
|
232
|
+
srcx += xstep;
|
233
|
+
srcy += ystep;
|
234
|
+
}
|
235
|
+
}
|
236
|
+
break;
|
237
|
+
|
238
|
+
case 2: { /* Probably 15-bpp or 16-bpp */
|
239
|
+
Uint16 *pixel;
|
240
|
+
Uint16 *row = (Uint16 *)dest->pixels + y*dest->pitch/2;
|
241
|
+
|
242
|
+
Uint16 pitch = source->pitch/2;
|
243
|
+
|
244
|
+
for (x = x1; x <= x2; x++){
|
245
|
+
pixel = row + x;
|
246
|
+
|
247
|
+
*pixel = *((Uint16 *)source->pixels + (srcy>>16)*pitch + (srcx>>16));
|
248
|
+
|
249
|
+
srcx += xstep;
|
250
|
+
srcy += ystep;
|
251
|
+
}
|
252
|
+
}
|
253
|
+
break;
|
254
|
+
|
255
|
+
case 3: { /* Slow 24-bpp mode, usually not used */
|
256
|
+
Uint8 *pixel, *srcpixel;
|
257
|
+
Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch;
|
258
|
+
|
259
|
+
Uint8 rshift8=dest->format->Rshift/8;
|
260
|
+
Uint8 gshift8=dest->format->Gshift/8;
|
261
|
+
Uint8 bshift8=dest->format->Bshift/8;
|
262
|
+
|
263
|
+
for (x = x1; x <= x2; x++){
|
264
|
+
pixel = row + x*3;
|
265
|
+
srcpixel = (Uint8 *)source->pixels + (srcy>>16)*source->pitch + (srcx>>16)*3;
|
266
|
+
|
267
|
+
*(pixel+rshift8) = *(srcpixel+rshift8);
|
268
|
+
*(pixel+gshift8) = *(srcpixel+gshift8);
|
269
|
+
*(pixel+bshift8) = *(srcpixel+bshift8);
|
270
|
+
|
271
|
+
srcx += xstep;
|
272
|
+
srcy += ystep;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
break;
|
276
|
+
|
277
|
+
case 4: { /* Probably 32-bpp */
|
278
|
+
Uint32 *pixel;
|
279
|
+
Uint32 *row = (Uint32 *)dest->pixels + y*dest->pitch/4;
|
280
|
+
|
281
|
+
Uint16 pitch = source->pitch/4;
|
282
|
+
|
283
|
+
for (x = x1; x <= x2; x++){
|
284
|
+
pixel = row + x;
|
285
|
+
|
286
|
+
*pixel = *((Uint32 *)source->pixels + (srcy>>16)*pitch + (srcx>>16));
|
287
|
+
|
288
|
+
srcx += xstep;
|
289
|
+
srcy += ystep;
|
290
|
+
}
|
291
|
+
}
|
292
|
+
break;
|
293
|
+
}
|
294
|
+
}else{
|
295
|
+
/* Slow mode. We must translate every pixel color! */
|
296
|
+
|
297
|
+
Uint8 r=0,g=0,b=0;
|
298
|
+
|
299
|
+
switch (dest->format->BytesPerPixel) {
|
300
|
+
case 1: { /* Assuming 8-bpp */
|
301
|
+
Uint8 *pixel;
|
302
|
+
Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch;
|
303
|
+
|
304
|
+
for (x = x1; x <= x2; x++){
|
305
|
+
pixel = row + x;
|
306
|
+
|
307
|
+
SDL_GetRGB(sge_GetPixel(source, srcx>>16, srcy>>16), source->format, &r, &g, &b);
|
308
|
+
*pixel = SDL_MapRGB( dest->format, r, g, b );
|
309
|
+
|
310
|
+
srcx += xstep;
|
311
|
+
srcy += ystep;
|
312
|
+
}
|
313
|
+
}
|
314
|
+
break;
|
315
|
+
|
316
|
+
case 2: { /* Probably 15-bpp or 16-bpp */
|
317
|
+
Uint16 *pixel;
|
318
|
+
Uint16 *row = (Uint16 *)dest->pixels + y*dest->pitch/2;
|
319
|
+
|
320
|
+
for (x = x1; x <= x2; x++){
|
321
|
+
pixel = row + x;
|
322
|
+
|
323
|
+
SDL_GetRGB(sge_GetPixel(source, srcx>>16, srcy>>16), source->format, &r, &g, &b);
|
324
|
+
*pixel = MapRGB( dest->format, r, g, b );
|
325
|
+
|
326
|
+
srcx += xstep;
|
327
|
+
srcy += ystep;
|
328
|
+
}
|
329
|
+
}
|
330
|
+
break;
|
331
|
+
|
332
|
+
case 3: { /* Slow 24-bpp mode, usually not used */
|
333
|
+
Uint8 *pixel, *srcpixel;
|
334
|
+
Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch;
|
335
|
+
|
336
|
+
Uint8 rshift8=dest->format->Rshift/8;
|
337
|
+
Uint8 gshift8=dest->format->Gshift/8;
|
338
|
+
Uint8 bshift8=dest->format->Bshift/8;
|
339
|
+
|
340
|
+
for (x = x1; x <= x2; x++){
|
341
|
+
pixel = row + x*3;
|
342
|
+
srcpixel = (Uint8 *)source->pixels + (srcy>>16)*source->pitch + (srcx>>16)*3;
|
343
|
+
|
344
|
+
SDL_GetRGB(sge_GetPixel(source, srcx>>16, srcy>>16), source->format, &r, &g, &b);
|
345
|
+
|
346
|
+
*(pixel+rshift8) = r;
|
347
|
+
*(pixel+gshift8) = g;
|
348
|
+
*(pixel+bshift8) = b;
|
349
|
+
|
350
|
+
srcx += xstep;
|
351
|
+
srcy += ystep;
|
352
|
+
}
|
353
|
+
}
|
354
|
+
break;
|
355
|
+
|
356
|
+
case 4: { /* Probably 32-bpp */
|
357
|
+
Uint32 *pixel;
|
358
|
+
Uint32 *row = (Uint32 *)dest->pixels + y*dest->pitch/4;
|
359
|
+
|
360
|
+
for (x = x1; x <= x2; x++){
|
361
|
+
pixel = row + x;
|
362
|
+
|
363
|
+
SDL_GetRGB(sge_GetPixel(source, srcx>>16, srcy>>16), source->format, &r, &g, &b);
|
364
|
+
*pixel = MapRGB( dest->format, r, g, b );
|
365
|
+
|
366
|
+
srcx += xstep;
|
367
|
+
srcy += ystep;
|
368
|
+
}
|
369
|
+
}
|
370
|
+
break;
|
371
|
+
}
|
372
|
+
}
|
373
|
+
}
|
374
|
+
|
375
|
+
void sge_TexturedLine(SDL_Surface *dest,Sint16 x1,Sint16 x2,Sint16 y,SDL_Surface *source,Sint16 sx1,Sint16 sy1,Sint16 sx2,Sint16 sy2)
|
376
|
+
{
|
377
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
378
|
+
if ( SDL_LockSurface(dest) < 0 )
|
379
|
+
return;
|
380
|
+
if ( SDL_MUSTLOCK(source) && _sge_lock )
|
381
|
+
if ( SDL_LockSurface(source) < 0 )
|
382
|
+
return;
|
383
|
+
|
384
|
+
_TexturedLine(dest,x1,x2,y,source,sx1,sy1,sx2,sy2);
|
385
|
+
|
386
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
387
|
+
SDL_UnlockSurface(dest);
|
388
|
+
if ( SDL_MUSTLOCK(source) && _sge_lock )
|
389
|
+
SDL_UnlockSurface(source);
|
390
|
+
|
391
|
+
if(_sge_update!=1){return;}
|
392
|
+
if ( x1 > x2 )
|
393
|
+
sge_UpdateRect(dest, x1, y, x1-x2+1, 1);
|
394
|
+
else
|
395
|
+
sge_UpdateRect(dest, x1, y, x2-x1+1, 1);
|
396
|
+
}
|
397
|
+
|
398
|
+
//==================================================================================
|
399
|
+
// Draws a trigon
|
400
|
+
//==================================================================================
|
401
|
+
void sge_Trigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color)
|
402
|
+
{
|
403
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
404
|
+
if ( SDL_LockSurface(dest) < 0 )
|
405
|
+
return;
|
406
|
+
|
407
|
+
_Line(dest,x1,y1,x2,y2,color);
|
408
|
+
_Line(dest,x1,y1,x3,y3,color);
|
409
|
+
_Line(dest,x3,y3,x2,y2,color);
|
410
|
+
|
411
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
412
|
+
SDL_UnlockSurface(dest);
|
413
|
+
|
414
|
+
if(_sge_update!=1){return;}
|
415
|
+
|
416
|
+
Sint16 xmax=x1, ymax=y1, xmin=x1, ymin=y1;
|
417
|
+
xmax= (xmax>x2)? xmax : x2; ymax= (ymax>y2)? ymax : y2;
|
418
|
+
xmin= (xmin<x2)? xmin : x2; ymin= (ymin<y2)? ymin : y2;
|
419
|
+
xmax= (xmax>x3)? xmax : x3; ymax= (ymax>y3)? ymax : y3;
|
420
|
+
xmin= (xmin<x3)? xmin : x3; ymin= (ymin<y3)? ymin : y3;
|
421
|
+
|
422
|
+
sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
|
423
|
+
}
|
424
|
+
|
425
|
+
void sge_Trigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B)
|
426
|
+
{
|
427
|
+
sge_Trigon(dest,x1,y1,x2,y2,x3,y3, SDL_MapRGB(dest->format, R,G,B));
|
428
|
+
}
|
429
|
+
|
430
|
+
|
431
|
+
//==================================================================================
|
432
|
+
// Draws a trigon (alpha)
|
433
|
+
//==================================================================================
|
434
|
+
void sge_TrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color, Uint8 alpha)
|
435
|
+
{
|
436
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
437
|
+
if ( SDL_LockSurface(dest) < 0 )
|
438
|
+
return;
|
439
|
+
|
440
|
+
_LineAlpha(dest,x1,y1,x2,y2,color,alpha);
|
441
|
+
_LineAlpha(dest,x1,y1,x3,y3,color,alpha);
|
442
|
+
_LineAlpha(dest,x3,y3,x2,y2,color,alpha);
|
443
|
+
|
444
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
445
|
+
SDL_UnlockSurface(dest);
|
446
|
+
|
447
|
+
|
448
|
+
if(_sge_update!=1){return;}
|
449
|
+
|
450
|
+
Sint16 xmax=x1, ymax=y1, xmin=x1, ymin=y1;
|
451
|
+
xmax= (xmax>x2)? xmax : x2; ymax= (ymax>y2)? ymax : y2;
|
452
|
+
xmin= (xmin<x2)? xmin : x2; ymin= (ymin<y2)? ymin : y2;
|
453
|
+
xmax= (xmax>x3)? xmax : x3; ymax= (ymax>y3)? ymax : y3;
|
454
|
+
xmin= (xmin<x3)? xmin : x3; ymin= (ymin<y3)? ymin : y3;
|
455
|
+
|
456
|
+
sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
|
457
|
+
}
|
458
|
+
|
459
|
+
void sge_TrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
|
460
|
+
{
|
461
|
+
sge_TrigonAlpha(dest,x1,y1,x2,y2,x3,y3, SDL_MapRGB(dest->format, R,G,B), alpha);
|
462
|
+
}
|
463
|
+
|
464
|
+
|
465
|
+
//==================================================================================
|
466
|
+
// Draws an AA trigon (alpha)
|
467
|
+
//==================================================================================
|
468
|
+
void sge_AATrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color, Uint8 alpha)
|
469
|
+
{
|
470
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
471
|
+
if ( SDL_LockSurface(dest) < 0 )
|
472
|
+
return;
|
473
|
+
|
474
|
+
_AALineAlpha(dest,x1,y1,x2,y2,color,alpha);
|
475
|
+
_AALineAlpha(dest,x1,y1,x3,y3,color,alpha);
|
476
|
+
_AALineAlpha(dest,x3,y3,x2,y2,color,alpha);
|
477
|
+
|
478
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
479
|
+
SDL_UnlockSurface(dest);
|
480
|
+
|
481
|
+
|
482
|
+
if(_sge_update!=1){return;}
|
483
|
+
|
484
|
+
Sint16 xmax=x1, ymax=y1, xmin=x1, ymin=y1;
|
485
|
+
xmax= (xmax>x2)? xmax : x2; ymax= (ymax>y2)? ymax : y2;
|
486
|
+
xmin= (xmin<x2)? xmin : x2; ymin= (ymin<y2)? ymin : y2;
|
487
|
+
xmax= (xmax>x3)? xmax : x3; ymax= (ymax>y3)? ymax : y3;
|
488
|
+
xmin= (xmin<x3)? xmin : x3; ymin= (ymin<y3)? ymin : y3;
|
489
|
+
|
490
|
+
sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
|
491
|
+
}
|
492
|
+
|
493
|
+
void sge_AATrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
|
494
|
+
{
|
495
|
+
sge_AATrigonAlpha(dest,x1,y1,x2,y2,x3,y3, SDL_MapRGB(dest->format, R,G,B), alpha);
|
496
|
+
}
|
497
|
+
|
498
|
+
void sge_AATrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color)
|
499
|
+
{
|
500
|
+
sge_AATrigonAlpha(dest,x1,y1,x2,y2,x3,y3, color, 255);
|
501
|
+
}
|
502
|
+
|
503
|
+
void sge_AATrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B)
|
504
|
+
{
|
505
|
+
sge_AATrigonAlpha(dest,x1,y1,x2,y2,x3,y3, SDL_MapRGB(dest->format, R,G,B), 255);
|
506
|
+
}
|
507
|
+
|
508
|
+
|
509
|
+
//==================================================================================
|
510
|
+
// Draws a filled trigon
|
511
|
+
//==================================================================================
|
512
|
+
void sge_FilledTrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color)
|
513
|
+
{
|
514
|
+
Sint16 y;
|
515
|
+
|
516
|
+
if( y1==y3 )
|
517
|
+
return;
|
518
|
+
|
519
|
+
/* Sort coords */
|
520
|
+
if ( y1 > y2 ) {
|
521
|
+
SWAP(y1,y2,y);
|
522
|
+
SWAP(x1,x2,y);
|
523
|
+
}
|
524
|
+
if ( y2 > y3 ) {
|
525
|
+
SWAP(y2,y3,y);
|
526
|
+
SWAP(x2,x3,y);
|
527
|
+
}
|
528
|
+
if ( y1 > y2 ) {
|
529
|
+
SWAP(y1,y2,y);
|
530
|
+
SWAP(x1,x2,y);
|
531
|
+
}
|
532
|
+
|
533
|
+
/*
|
534
|
+
* How do we calculate the starting and ending x coordinate of the horizontal line
|
535
|
+
* on each y coordinate? We can do this by using a standard line algorithm but
|
536
|
+
* instead of plotting pixels, use the x coordinates as start and stop
|
537
|
+
* coordinates for the horizontal line.
|
538
|
+
* So we will simply trace the outlining of the triangle; this will require 3 lines.
|
539
|
+
* Line 1 is the line between (x1,y1) and (x2,y2)
|
540
|
+
* Line 2 is the line between (x1,y1) and (x3,y3)
|
541
|
+
* Line 3 is the line between (x2,y2) and (x3,y3)
|
542
|
+
*
|
543
|
+
* We can divide the triangle into 2 halfs. The upper half will be outlined by line
|
544
|
+
* 1 and 2. The lower half will be outlined by line line 2 and 3.
|
545
|
+
*/
|
546
|
+
|
547
|
+
|
548
|
+
/* Starting coords for the three lines */
|
549
|
+
Sint32 xa = Sint32(x1<<16);
|
550
|
+
Sint32 xb = xa;
|
551
|
+
Sint32 xc = Sint32(x2<<16);
|
552
|
+
|
553
|
+
/* Lines step values */
|
554
|
+
Sint32 m1 = 0;
|
555
|
+
Sint32 m2 = Sint32((x3 - x1)<<16)/Sint32(y3 - y1);
|
556
|
+
Sint32 m3 = 0;
|
557
|
+
|
558
|
+
/* Upper half of the triangle */
|
559
|
+
if( y1==y2 )
|
560
|
+
_HLine(dest, x1, x2, y1, color);
|
561
|
+
else{
|
562
|
+
m1 = Sint32((x2 - x1)<<16)/Sint32(y2 - y1);
|
563
|
+
|
564
|
+
for ( y = y1; y <= y2; y++) {
|
565
|
+
_HLine(dest, xa>>16, xb>>16, y, color);
|
566
|
+
|
567
|
+
xa += m1;
|
568
|
+
xb += m2;
|
569
|
+
}
|
570
|
+
}
|
571
|
+
|
572
|
+
/* Lower half of the triangle */
|
573
|
+
if( y2==y3 )
|
574
|
+
_HLine(dest, x2, x3, y2, color);
|
575
|
+
else{
|
576
|
+
m3 = Sint32((x3 - x2)<<16)/Sint32(y3 - y2);
|
577
|
+
|
578
|
+
for ( y = y2+1; y <= y3; y++) {
|
579
|
+
_HLine(dest, xb>>16, xc>>16, y, color);
|
580
|
+
|
581
|
+
xb += m2;
|
582
|
+
xc += m3;
|
583
|
+
}
|
584
|
+
}
|
585
|
+
|
586
|
+
|
587
|
+
if(_sge_update!=1){return;}
|
588
|
+
|
589
|
+
Sint16 xmax=x1, xmin=x1;
|
590
|
+
xmax= (xmax>x2)? xmax : x2;
|
591
|
+
xmin= (xmin<x2)? xmin : x2;
|
592
|
+
xmax= (xmax>x3)? xmax : x3;
|
593
|
+
xmin= (xmin<x3)? xmin : x3;
|
594
|
+
|
595
|
+
sge_UpdateRect(dest, xmin, y1, xmax-xmin+1, y3-y1+1);
|
596
|
+
}
|
597
|
+
|
598
|
+
void sge_FilledTrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B)
|
599
|
+
{
|
600
|
+
sge_FilledTrigon(dest,x1,y1,x2,y2,x3,y3, SDL_MapRGB(dest->format, R,G,B));
|
601
|
+
}
|
602
|
+
|
603
|
+
|
604
|
+
//==================================================================================
|
605
|
+
// Draws a filled trigon (alpha)
|
606
|
+
//==================================================================================
|
607
|
+
void sge_FilledTrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color, Uint8 alpha)
|
608
|
+
{
|
609
|
+
Sint16 y;
|
610
|
+
|
611
|
+
if( y1==y3 )
|
612
|
+
return;
|
613
|
+
|
614
|
+
/* Sort coords */
|
615
|
+
if ( y1 > y2 ) {
|
616
|
+
SWAP(y1,y2,y);
|
617
|
+
SWAP(x1,x2,y);
|
618
|
+
}
|
619
|
+
if ( y2 > y3 ) {
|
620
|
+
SWAP(y2,y3,y);
|
621
|
+
SWAP(x2,x3,y);
|
622
|
+
}
|
623
|
+
if ( y1 > y2 ) {
|
624
|
+
SWAP(y1,y2,y);
|
625
|
+
SWAP(x1,x2,y);
|
626
|
+
}
|
627
|
+
|
628
|
+
Sint32 xa = Sint32(x1<<16);
|
629
|
+
Sint32 xb = xa;
|
630
|
+
Sint32 xc = Sint32(x2<<16);
|
631
|
+
|
632
|
+
Sint32 m1 = 0;
|
633
|
+
Sint32 m2 = Sint32((x3 - x1)<<16)/Sint32(y3 - y1);
|
634
|
+
Sint32 m3 = 0;
|
635
|
+
|
636
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
637
|
+
if ( SDL_LockSurface(dest) < 0 )
|
638
|
+
return;
|
639
|
+
|
640
|
+
/* Upper half of the triangle */
|
641
|
+
if( y1==y2 )
|
642
|
+
_HLineAlpha(dest, x1, x2, y1, color, alpha);
|
643
|
+
else{
|
644
|
+
m1 = Sint32((x2 - x1)<<16)/Sint32(y2 - y1);
|
645
|
+
|
646
|
+
for ( y = y1; y <= y2; y++) {
|
647
|
+
_HLineAlpha(dest, xa>>16, xb>>16, y, color, alpha);
|
648
|
+
|
649
|
+
xa += m1;
|
650
|
+
xb += m2;
|
651
|
+
}
|
652
|
+
}
|
653
|
+
|
654
|
+
/* Lower half of the triangle */
|
655
|
+
if( y2==y3 )
|
656
|
+
_HLineAlpha(dest, x2, x3, y2, color, alpha);
|
657
|
+
else{
|
658
|
+
m3 = Sint32((x3 - x2)<<16)/Sint32(y3 - y2);
|
659
|
+
|
660
|
+
for ( y = y2+1; y <= y3; y++) {
|
661
|
+
_HLineAlpha(dest, xb>>16, xc>>16, y, color, alpha);
|
662
|
+
|
663
|
+
xb += m2;
|
664
|
+
xc += m3;
|
665
|
+
}
|
666
|
+
}
|
667
|
+
|
668
|
+
|
669
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
670
|
+
SDL_UnlockSurface(dest);
|
671
|
+
|
672
|
+
|
673
|
+
if(_sge_update!=1){return;}
|
674
|
+
|
675
|
+
Sint16 xmax=x1, xmin=x1;
|
676
|
+
xmax= (xmax>x2)? xmax : x2;
|
677
|
+
xmin= (xmin<x2)? xmin : x2;
|
678
|
+
xmax= (xmax>x3)? xmax : x3;
|
679
|
+
xmin= (xmin<x3)? xmin : x3;
|
680
|
+
|
681
|
+
sge_UpdateRect(dest, xmin, y1, xmax-xmin+1, y3-y1+1);
|
682
|
+
}
|
683
|
+
|
684
|
+
void sge_FilledTrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
|
685
|
+
{
|
686
|
+
sge_FilledTrigonAlpha(dest,x1,y1,x2,y2,x3,y3, SDL_MapRGB(dest->format, R,G,B),alpha);
|
687
|
+
}
|
688
|
+
|
689
|
+
|
690
|
+
//==================================================================================
|
691
|
+
// Draws a gourand shaded trigon
|
692
|
+
//==================================================================================
|
693
|
+
void sge_FadedTrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 c1,Uint32 c2,Uint32 c3)
|
694
|
+
{
|
695
|
+
Sint16 y;
|
696
|
+
|
697
|
+
if( y1==y3 )
|
698
|
+
return;
|
699
|
+
|
700
|
+
Uint8 c=0;
|
701
|
+
SDL_Color col1;
|
702
|
+
SDL_Color col2;
|
703
|
+
SDL_Color col3;
|
704
|
+
|
705
|
+
col1 = sge_GetRGB(dest,c1);
|
706
|
+
col2 = sge_GetRGB(dest,c2);
|
707
|
+
col3 = sge_GetRGB(dest,c3);
|
708
|
+
|
709
|
+
/* Sort coords */
|
710
|
+
if ( y1 > y2 ) {
|
711
|
+
SWAP(y1,y2,y);
|
712
|
+
SWAP(x1,x2,y);
|
713
|
+
SWAP(col1.r,col2.r,c);
|
714
|
+
SWAP(col1.g,col2.g,c);
|
715
|
+
SWAP(col1.b,col2.b,c);
|
716
|
+
}
|
717
|
+
if ( y2 > y3 ) {
|
718
|
+
SWAP(y2,y3,y);
|
719
|
+
SWAP(x2,x3,y);
|
720
|
+
SWAP(col2.r,col3.r,c);
|
721
|
+
SWAP(col2.g,col3.g,c);
|
722
|
+
SWAP(col2.b,col3.b,c);
|
723
|
+
}
|
724
|
+
if ( y1 > y2 ) {
|
725
|
+
SWAP(y1,y2,y);
|
726
|
+
SWAP(x1,x2,y);
|
727
|
+
SWAP(col1.r,col2.r,c);
|
728
|
+
SWAP(col1.g,col2.g,c);
|
729
|
+
SWAP(col1.b,col2.b,c);
|
730
|
+
}
|
731
|
+
|
732
|
+
/*
|
733
|
+
* We trace three lines exactly like in sge_FilledTrigon(), but here we
|
734
|
+
* must also keep track of the colors. We simply calculate how the color
|
735
|
+
* will change along the three lines.
|
736
|
+
*/
|
737
|
+
|
738
|
+
/* Starting coords for the three lines */
|
739
|
+
Sint32 xa = Sint32(x1<<16);
|
740
|
+
Sint32 xb = xa;
|
741
|
+
Sint32 xc = Sint32(x2<<16);
|
742
|
+
|
743
|
+
/* Starting colors (rgb) for the three lines */
|
744
|
+
Sint32 r1 = Sint32(col1.r<<16);
|
745
|
+
Sint32 r2 = r1;
|
746
|
+
Sint32 r3 = Sint32(col2.r<<16);
|
747
|
+
|
748
|
+
Sint32 g1 = Sint32(col1.g<<16);
|
749
|
+
Sint32 g2 = g1;
|
750
|
+
Sint32 g3 = Sint32(col2.g<<16);
|
751
|
+
|
752
|
+
Sint32 b1 = Sint32(col1.b<<16);
|
753
|
+
Sint32 b2 = b1;
|
754
|
+
Sint32 b3 = Sint32(col2.b<<16);
|
755
|
+
|
756
|
+
/* Lines step values */
|
757
|
+
Sint32 m1 = 0;
|
758
|
+
Sint32 m2 = Sint32((x3 - x1)<<16)/Sint32(y3 - y1);
|
759
|
+
Sint32 m3 = 0;
|
760
|
+
|
761
|
+
/* Colors step values */
|
762
|
+
Sint32 rstep1 = 0;
|
763
|
+
Sint32 rstep2 = Sint32((col3.r - col1.r) << 16) / Sint32(y3 - y1);
|
764
|
+
Sint32 rstep3 = 0;
|
765
|
+
|
766
|
+
Sint32 gstep1 = 0;
|
767
|
+
Sint32 gstep2 = Sint32((col3.g - col1.g) << 16) / Sint32(y3 - y1);
|
768
|
+
Sint32 gstep3 = 0;
|
769
|
+
|
770
|
+
Sint32 bstep1 = 0;
|
771
|
+
Sint32 bstep2 = Sint32((col3.b - col1.b) << 16) / Sint32(y3 - y1);
|
772
|
+
Sint32 bstep3 = 0;
|
773
|
+
|
774
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
775
|
+
if ( SDL_LockSurface(dest) < 0 )
|
776
|
+
return;
|
777
|
+
|
778
|
+
/* Upper half of the triangle */
|
779
|
+
if( y1==y2 )
|
780
|
+
_FadedLine(dest, x1, x2, y1, col1.r, col1.g, col1.b, col2.r, col2.g, col2.b);
|
781
|
+
else{
|
782
|
+
m1 = Sint32((x2 - x1)<<16)/Sint32(y2 - y1);
|
783
|
+
|
784
|
+
rstep1 = Sint32((col2.r - col1.r) << 16) / Sint32(y2 - y1);
|
785
|
+
gstep1 = Sint32((col2.g - col1.g) << 16) / Sint32(y2 - y1);
|
786
|
+
bstep1 = Sint32((col2.b - col1.b) << 16) / Sint32(y2 - y1);
|
787
|
+
|
788
|
+
for ( y = y1; y <= y2; y++) {
|
789
|
+
_FadedLine(dest, xa>>16, xb>>16, y, r1>>16, g1>>16, b1>>16, r2>>16, g2>>16, b2>>16);
|
790
|
+
|
791
|
+
xa += m1;
|
792
|
+
xb += m2;
|
793
|
+
|
794
|
+
r1 += rstep1;
|
795
|
+
g1 += gstep1;
|
796
|
+
b1 += bstep1;
|
797
|
+
|
798
|
+
r2 += rstep2;
|
799
|
+
g2 += gstep2;
|
800
|
+
b2 += bstep2;
|
801
|
+
}
|
802
|
+
}
|
803
|
+
|
804
|
+
/* Lower half of the triangle */
|
805
|
+
if( y2==y3 )
|
806
|
+
_FadedLine(dest, x2, x3, y2, col2.r, col2.g, col2.b, col3.r, col3.g, col3.b);
|
807
|
+
else{
|
808
|
+
m3 = Sint32((x3 - x2)<<16)/Sint32(y3 - y2);
|
809
|
+
|
810
|
+
rstep3 = Sint32((col3.r - col2.r) << 16) / Sint32(y3 - y2);
|
811
|
+
gstep3 = Sint32((col3.g - col2.g) << 16) / Sint32(y3 - y2);
|
812
|
+
bstep3 = Sint32((col3.b - col2.b) << 16) / Sint32(y3 - y2);
|
813
|
+
|
814
|
+
for ( y = y2+1; y <= y3; y++) {
|
815
|
+
_FadedLine(dest, xb>>16, xc>>16, y, r2>>16, g2>>16, b2>>16, r3>>16, g3>>16, b3>>16);
|
816
|
+
|
817
|
+
xb += m2;
|
818
|
+
xc += m3;
|
819
|
+
|
820
|
+
r2 += rstep2;
|
821
|
+
g2 += gstep2;
|
822
|
+
b2 += bstep2;
|
823
|
+
|
824
|
+
r3 += rstep3;
|
825
|
+
g3 += gstep3;
|
826
|
+
b3 += bstep3;
|
827
|
+
}
|
828
|
+
}
|
829
|
+
|
830
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
831
|
+
SDL_UnlockSurface(dest);
|
832
|
+
|
833
|
+
if(_sge_update!=1){return;}
|
834
|
+
|
835
|
+
Sint16 xmax=x1, xmin=x1;
|
836
|
+
xmax= (xmax>x2)? xmax : x2;
|
837
|
+
xmin= (xmin<x2)? xmin : x2;
|
838
|
+
xmax= (xmax>x3)? xmax : x3;
|
839
|
+
xmin= (xmin<x3)? xmin : x3;
|
840
|
+
|
841
|
+
sge_UpdateRect(dest, xmin, y1, xmax-xmin+1, y3-y1+1);
|
842
|
+
}
|
843
|
+
|
844
|
+
|
845
|
+
//==================================================================================
|
846
|
+
// Draws a texured trigon (fast)
|
847
|
+
//==================================================================================
|
848
|
+
void sge_TexturedTrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,SDL_Surface *source,Sint16 sx1,Sint16 sy1,Sint16 sx2,Sint16 sy2,Sint16 sx3,Sint16 sy3)
|
849
|
+
{
|
850
|
+
Sint16 y;
|
851
|
+
|
852
|
+
if( y1==y3 )
|
853
|
+
return;
|
854
|
+
|
855
|
+
/* Sort coords */
|
856
|
+
if ( y1 > y2 ) {
|
857
|
+
SWAP(y1,y2,y);
|
858
|
+
SWAP(x1,x2,y);
|
859
|
+
SWAP(sx1,sx2,y);
|
860
|
+
SWAP(sy1,sy2,y);
|
861
|
+
}
|
862
|
+
if ( y2 > y3 ) {
|
863
|
+
SWAP(y2,y3,y);
|
864
|
+
SWAP(x2,x3,y);
|
865
|
+
SWAP(sx2,sx3,y);
|
866
|
+
SWAP(sy2,sy3,y);
|
867
|
+
}
|
868
|
+
if ( y1 > y2 ) {
|
869
|
+
SWAP(y1,y2,y);
|
870
|
+
SWAP(x1,x2,y);
|
871
|
+
SWAP(sx1,sx2,y);
|
872
|
+
SWAP(sy1,sy2,y);
|
873
|
+
}
|
874
|
+
|
875
|
+
/*
|
876
|
+
* Again we do the same thing as in sge_FilledTrigon(). But here we must keep track of how the
|
877
|
+
* texture coords change along the lines.
|
878
|
+
*/
|
879
|
+
|
880
|
+
/* Starting coords for the three lines */
|
881
|
+
Sint32 xa = Sint32(x1<<16);
|
882
|
+
Sint32 xb = xa;
|
883
|
+
Sint32 xc = Sint32(x2<<16);
|
884
|
+
|
885
|
+
/* Lines step values */
|
886
|
+
Sint32 m1 = 0;
|
887
|
+
Sint32 m2 = Sint32((x3 - x1)<<16)/Sint32(y3 - y1);
|
888
|
+
Sint32 m3 = 0;
|
889
|
+
|
890
|
+
/* Starting texture coords for the three lines */
|
891
|
+
Sint32 srcx1 = Sint32(sx1<<16);
|
892
|
+
Sint32 srcx2 = srcx1;
|
893
|
+
Sint32 srcx3 = Sint32(sx2<<16);
|
894
|
+
|
895
|
+
Sint32 srcy1 = Sint32(sy1<<16);
|
896
|
+
Sint32 srcy2 = srcy1;
|
897
|
+
Sint32 srcy3 = Sint32(sy2<<16);
|
898
|
+
|
899
|
+
/* Texture coords stepping value */
|
900
|
+
Sint32 xstep1 = 0;
|
901
|
+
Sint32 xstep2 = Sint32((sx3 - sx1) << 16) / Sint32(y3 - y1);
|
902
|
+
Sint32 xstep3 = 0;
|
903
|
+
|
904
|
+
Sint32 ystep1 = 0;
|
905
|
+
Sint32 ystep2 = Sint32((sy3 - sy1) << 16) / Sint32(y3 - y1);
|
906
|
+
Sint32 ystep3 = 0;
|
907
|
+
|
908
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
909
|
+
if ( SDL_LockSurface(dest) < 0 )
|
910
|
+
return;
|
911
|
+
if ( SDL_MUSTLOCK(source) && _sge_lock )
|
912
|
+
if ( SDL_LockSurface(source) < 0 )
|
913
|
+
return;
|
914
|
+
|
915
|
+
/* Upper half of the triangle */
|
916
|
+
if( y1==y2 )
|
917
|
+
_TexturedLine(dest,x1,x2,y1,source,sx1,sy1,sx2,sy2);
|
918
|
+
else{
|
919
|
+
m1 = Sint32((x2 - x1)<<16)/Sint32(y2 - y1);
|
920
|
+
|
921
|
+
xstep1 = Sint32((sx2 - sx1) << 16) / Sint32(y2 - y1);
|
922
|
+
ystep1 = Sint32((sy2 - sy1) << 16) / Sint32(y2 - y1);
|
923
|
+
|
924
|
+
for ( y = y1; y <= y2; y++) {
|
925
|
+
_TexturedLine(dest, xa>>16, xb>>16, y, source, srcx1>>16, srcy1>>16, srcx2>>16, srcy2>>16);
|
926
|
+
|
927
|
+
xa += m1;
|
928
|
+
xb += m2;
|
929
|
+
|
930
|
+
srcx1 += xstep1;
|
931
|
+
srcx2 += xstep2;
|
932
|
+
srcy1 += ystep1;
|
933
|
+
srcy2 += ystep2;
|
934
|
+
}
|
935
|
+
}
|
936
|
+
|
937
|
+
/* Lower half of the triangle */
|
938
|
+
if( y2==y3 )
|
939
|
+
_TexturedLine(dest,x2,x3,y2,source,sx2,sy2,sx3,sy3);
|
940
|
+
else{
|
941
|
+
m3 = Sint32((x3 - x2)<<16)/Sint32(y3 - y2);
|
942
|
+
|
943
|
+
xstep3 = Sint32((sx3 - sx2) << 16) / Sint32(y3 - y2);
|
944
|
+
ystep3 = Sint32((sy3 - sy2) << 16) / Sint32(y3 - y2);
|
945
|
+
|
946
|
+
for ( y = y2+1; y <= y3; y++) {
|
947
|
+
_TexturedLine(dest, xb>>16, xc>>16, y, source, srcx2>>16, srcy2>>16, srcx3>>16, srcy3>>16);
|
948
|
+
|
949
|
+
xb += m2;
|
950
|
+
xc += m3;
|
951
|
+
|
952
|
+
srcx2 += xstep2;
|
953
|
+
srcx3 += xstep3;
|
954
|
+
srcy2 += ystep2;
|
955
|
+
srcy3 += ystep3;
|
956
|
+
}
|
957
|
+
}
|
958
|
+
|
959
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
960
|
+
SDL_UnlockSurface(dest);
|
961
|
+
if ( SDL_MUSTLOCK(source) && _sge_lock )
|
962
|
+
SDL_UnlockSurface(source);
|
963
|
+
|
964
|
+
if(_sge_update!=1){return;}
|
965
|
+
|
966
|
+
Sint16 xmax=x1, xmin=x1;
|
967
|
+
xmax= (xmax>x2)? xmax : x2;
|
968
|
+
xmin= (xmin<x2)? xmin : x2;
|
969
|
+
xmax= (xmax>x3)? xmax : x3;
|
970
|
+
xmin= (xmin<x3)? xmin : x3;
|
971
|
+
|
972
|
+
sge_UpdateRect(dest, xmin, y1, xmax-xmin+1, y3-y1+1);
|
973
|
+
}
|
974
|
+
|
975
|
+
|
976
|
+
//==================================================================================
|
977
|
+
// Draws a texured *RECTANGLE*
|
978
|
+
//==================================================================================
|
979
|
+
void sge_TexturedRect(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Sint16 x4,Sint16 y4,SDL_Surface *source,Sint16 sx1,Sint16 sy1,Sint16 sx2,Sint16 sy2,Sint16 sx3,Sint16 sy3,Sint16 sx4,Sint16 sy4)
|
980
|
+
{
|
981
|
+
Sint16 y;
|
982
|
+
|
983
|
+
if( y1==y3 || y1 == y4 || y4 == y2 )
|
984
|
+
return;
|
985
|
+
|
986
|
+
/* Sort the coords */
|
987
|
+
if ( y1 > y2 ) {
|
988
|
+
SWAP(x1,x2,y);
|
989
|
+
SWAP(y1,y2,y);
|
990
|
+
SWAP(sx1,sx2,y);
|
991
|
+
SWAP(sy1,sy2,y);
|
992
|
+
}
|
993
|
+
if ( y2 > y3 ) {
|
994
|
+
SWAP(x3,x2,y);
|
995
|
+
SWAP(y3,y2,y);
|
996
|
+
SWAP(sx3,sx2,y);
|
997
|
+
SWAP(sy3,sy2,y);
|
998
|
+
}
|
999
|
+
if ( y1 > y2 ) {
|
1000
|
+
SWAP(x1,x2,y);
|
1001
|
+
SWAP(y1,y2,y);
|
1002
|
+
SWAP(sx1,sx2,y);
|
1003
|
+
SWAP(sy1,sy2,y);
|
1004
|
+
}
|
1005
|
+
if ( y3 > y4 ) {
|
1006
|
+
SWAP(x3,x4,y);
|
1007
|
+
SWAP(y3,y4,y);
|
1008
|
+
SWAP(sx3,sx4,y);
|
1009
|
+
SWAP(sy3,sy4,y);
|
1010
|
+
}
|
1011
|
+
if ( y2 > y3 ) {
|
1012
|
+
SWAP(x3,x2,y);
|
1013
|
+
SWAP(y3,y2,y);
|
1014
|
+
SWAP(sx3,sx2,y);
|
1015
|
+
SWAP(sy3,sy2,y);
|
1016
|
+
}
|
1017
|
+
if ( y1 > y2 ) {
|
1018
|
+
SWAP(x1,x2,y);
|
1019
|
+
SWAP(y1,y2,y);
|
1020
|
+
SWAP(sx1,sx2,y);
|
1021
|
+
SWAP(sy1,sy2,y);
|
1022
|
+
}
|
1023
|
+
|
1024
|
+
/*
|
1025
|
+
* We do this exactly like sge_TexturedTrigon(), but here we must trace four lines.
|
1026
|
+
*/
|
1027
|
+
|
1028
|
+
Sint32 xa = Sint32(x1<<16);
|
1029
|
+
Sint32 xb = xa;
|
1030
|
+
Sint32 xc = Sint32(x2<<16);
|
1031
|
+
Sint32 xd = Sint32(x3<<16);
|
1032
|
+
|
1033
|
+
Sint32 m1 = 0;
|
1034
|
+
Sint32 m2 = Sint32((x3 - x1)<<16)/Sint32(y3 - y1);
|
1035
|
+
Sint32 m3 = Sint32((x4 - x2)<<16)/Sint32(y4 - y2);
|
1036
|
+
Sint32 m4 = 0;
|
1037
|
+
|
1038
|
+
Sint32 srcx1 = Sint32(sx1<<16);
|
1039
|
+
Sint32 srcx2 = srcx1;
|
1040
|
+
Sint32 srcx3 = Sint32(sx2<<16);
|
1041
|
+
Sint32 srcx4 = Sint32(sx3<<16);
|
1042
|
+
|
1043
|
+
Sint32 srcy1 = Sint32(sy1<<16);
|
1044
|
+
Sint32 srcy2 = srcy1;
|
1045
|
+
Sint32 srcy3 = Sint32(sy2<<16);
|
1046
|
+
Sint32 srcy4 = Sint32(sy3<<16);
|
1047
|
+
|
1048
|
+
Sint32 xstep1 = 0;
|
1049
|
+
Sint32 xstep2 = Sint32((sx3 - sx1) << 16) / Sint32(y3 - y1);
|
1050
|
+
Sint32 xstep3 = Sint32((sx4 - sx2) << 16) / Sint32(y4 - y2);
|
1051
|
+
Sint32 xstep4 = 0;
|
1052
|
+
|
1053
|
+
Sint32 ystep1 = 0;
|
1054
|
+
Sint32 ystep2 = Sint32((sy3 - sy1) << 16) / Sint32(y3 - y1);
|
1055
|
+
Sint32 ystep3 = Sint32((sy4 - sy2) << 16) / Sint32(y4 - y2);
|
1056
|
+
Sint32 ystep4 = 0;
|
1057
|
+
|
1058
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
1059
|
+
if ( SDL_LockSurface(dest) < 0 )
|
1060
|
+
return;
|
1061
|
+
|
1062
|
+
/* Upper bit of the rectangle */
|
1063
|
+
if( y1==y2 )
|
1064
|
+
_TexturedLine(dest,x1,x2,y1,source,sx1,sy1,sx2,sy2);
|
1065
|
+
else{
|
1066
|
+
m1 = Sint32((x2 - x1)<<16)/Sint32(y2 - y1);
|
1067
|
+
|
1068
|
+
xstep1 = Sint32((sx2 - sx1) << 16) / Sint32(y2 - y1);
|
1069
|
+
ystep1 = Sint32((sy2 - sy1) << 16) / Sint32(y2 - y1);
|
1070
|
+
|
1071
|
+
for ( y = y1; y <= y2; y++) {
|
1072
|
+
_TexturedLine(dest, xa>>16, xb>>16, y, source, srcx1>>16, srcy1>>16, srcx2>>16, srcy2>>16);
|
1073
|
+
|
1074
|
+
xa += m1;
|
1075
|
+
xb += m2;
|
1076
|
+
|
1077
|
+
srcx1 += xstep1;
|
1078
|
+
srcx2 += xstep2;
|
1079
|
+
srcy1 += ystep1;
|
1080
|
+
srcy2 += ystep2;
|
1081
|
+
}
|
1082
|
+
}
|
1083
|
+
|
1084
|
+
/* Middle bit of the rectangle */
|
1085
|
+
for ( y = y2+1; y <= y3; y++) {
|
1086
|
+
_TexturedLine(dest, xb>>16, xc>>16, y, source, srcx2>>16, srcy2>>16, srcx3>>16, srcy3>>16);
|
1087
|
+
|
1088
|
+
xb += m2;
|
1089
|
+
xc += m3;
|
1090
|
+
|
1091
|
+
srcx2 += xstep2;
|
1092
|
+
srcx3 += xstep3;
|
1093
|
+
srcy2 += ystep2;
|
1094
|
+
srcy3 += ystep3;
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
/* Lower bit of the rectangle */
|
1098
|
+
if( y3==y4 )
|
1099
|
+
_TexturedLine(dest,x3,x4,y3,source,sx3,sy3,sx4,sy4);
|
1100
|
+
else{
|
1101
|
+
m4 = Sint32((x4 - x3)<<16)/Sint32(y4 - y3);
|
1102
|
+
|
1103
|
+
xstep4 = Sint32((sx4 - sx3) << 16) / Sint32(y4 - y3);
|
1104
|
+
ystep4 = Sint32((sy4 - sy3) << 16) / Sint32(y4 - y3);
|
1105
|
+
|
1106
|
+
for ( y = y3+1; y <= y4; y++) {
|
1107
|
+
_TexturedLine(dest, xc>>16, xd>>16, y, source, srcx3>>16, srcy3>>16, srcx4>>16, srcy4>>16);
|
1108
|
+
|
1109
|
+
xc += m3;
|
1110
|
+
xd += m4;
|
1111
|
+
|
1112
|
+
srcx3 += xstep3;
|
1113
|
+
srcx4 += xstep4;
|
1114
|
+
srcy3 += ystep3;
|
1115
|
+
srcy4 += ystep4;
|
1116
|
+
}
|
1117
|
+
|
1118
|
+
}
|
1119
|
+
|
1120
|
+
|
1121
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
1122
|
+
SDL_UnlockSurface(dest);
|
1123
|
+
|
1124
|
+
if(_sge_update!=1){return;}
|
1125
|
+
|
1126
|
+
Sint16 xmax=x1, xmin=x1;
|
1127
|
+
xmax= (xmax>x2)? xmax : x2;
|
1128
|
+
xmin= (xmin<x2)? xmin : x2;
|
1129
|
+
xmax= (xmax>x3)? xmax : x3;
|
1130
|
+
xmin= (xmin<x3)? xmin : x3;
|
1131
|
+
xmax= (xmax>x4)? xmax : x4;
|
1132
|
+
xmin= (xmin<x4)? xmin : x4;
|
1133
|
+
|
1134
|
+
sge_UpdateRect(dest, xmin, y1, xmax-xmin+1, y4-y1+1);
|
1135
|
+
}
|
1136
|
+
|
1137
|
+
|
1138
|
+
|
1139
|
+
//==================================================================================
|
1140
|
+
// And now to something completly different: Polygons!
|
1141
|
+
//==================================================================================
|
1142
|
+
|
1143
|
+
/* Base polygon structure */
|
1144
|
+
class pline{
|
1145
|
+
public:
|
1146
|
+
Sint16 x1,x2, y1,y2;
|
1147
|
+
|
1148
|
+
Sint32 fx, fm;
|
1149
|
+
|
1150
|
+
Sint16 x;
|
1151
|
+
|
1152
|
+
pline *next;
|
1153
|
+
|
1154
|
+
virtual void update(void)
|
1155
|
+
{
|
1156
|
+
x = Sint16(fx>>16);
|
1157
|
+
fx += fm;
|
1158
|
+
}
|
1159
|
+
};
|
1160
|
+
|
1161
|
+
/* Pointer storage (to preserve polymorphism) */
|
1162
|
+
struct pline_p{
|
1163
|
+
pline *p;
|
1164
|
+
};
|
1165
|
+
|
1166
|
+
/* Radix sort */
|
1167
|
+
pline* rsort(pline *inlist)
|
1168
|
+
{
|
1169
|
+
if(!inlist)
|
1170
|
+
return NULL;
|
1171
|
+
|
1172
|
+
// 16 radix-buckets
|
1173
|
+
pline* bucket[16] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
|
1174
|
+
pline* bi[16]; // bucket itterator (points to last element in bucket)
|
1175
|
+
|
1176
|
+
pline *plist = inlist;
|
1177
|
+
|
1178
|
+
int i,k;
|
1179
|
+
pline *j;
|
1180
|
+
Uint8 nr;
|
1181
|
+
|
1182
|
+
// Radix sort in 4 steps (16-bit numbers)
|
1183
|
+
for( i = 0; i < 4; i++ ){
|
1184
|
+
for( j = plist; j; j = j->next ){
|
1185
|
+
nr = Uint8( ( j->x >> (4*i) ) & 0x000F); // Get bucket number
|
1186
|
+
|
1187
|
+
if( !bucket[nr] )
|
1188
|
+
bucket[nr] = j; // First in bucket
|
1189
|
+
else
|
1190
|
+
bi[nr]->next = j; // Put last in bucket
|
1191
|
+
|
1192
|
+
bi[nr] = j; // Update bucket itterator
|
1193
|
+
}
|
1194
|
+
|
1195
|
+
// Empty buckets (recombine list)
|
1196
|
+
j = NULL;
|
1197
|
+
for( k = 0; k < 16; k++ ){
|
1198
|
+
if( bucket[k] ){
|
1199
|
+
if( j )
|
1200
|
+
j->next = bucket[k]; // Connect elements in buckets
|
1201
|
+
else
|
1202
|
+
plist = bucket[k]; // First element
|
1203
|
+
|
1204
|
+
j = bi[k];
|
1205
|
+
}
|
1206
|
+
bucket[k] = NULL; // Empty
|
1207
|
+
}
|
1208
|
+
j->next = NULL; // Terminate list
|
1209
|
+
}
|
1210
|
+
|
1211
|
+
return plist;
|
1212
|
+
}
|
1213
|
+
|
1214
|
+
/* Calculate the scanline for y */
|
1215
|
+
pline* get_scanline(pline_p *plist, Uint16 n, Sint32 y)
|
1216
|
+
{
|
1217
|
+
pline* p = NULL;
|
1218
|
+
pline* list = NULL;
|
1219
|
+
pline* li = NULL;
|
1220
|
+
|
1221
|
+
for( int i = 0; i < n; i++ ){
|
1222
|
+
// Is polyline on this scanline?
|
1223
|
+
p = plist[i].p;
|
1224
|
+
if( p->y1 <= y && p->y2 >= y && (p->y1 != p->y2) ){
|
1225
|
+
if( list )
|
1226
|
+
li->next = p; // Add last in list
|
1227
|
+
else
|
1228
|
+
list = p; // Add first in list
|
1229
|
+
|
1230
|
+
li = p; // Update itterator
|
1231
|
+
|
1232
|
+
// Calculate x
|
1233
|
+
p->update();
|
1234
|
+
}
|
1235
|
+
}
|
1236
|
+
|
1237
|
+
if( li )
|
1238
|
+
li->next = NULL; // terminate
|
1239
|
+
|
1240
|
+
// Sort list
|
1241
|
+
return rsort(list);
|
1242
|
+
}
|
1243
|
+
|
1244
|
+
/* Removes duplicates if needed */
|
1245
|
+
inline void remove_dup(pline *li, Sint16 y)
|
1246
|
+
{
|
1247
|
+
if( li->next )
|
1248
|
+
if( (y==li->y1 || y==li->y2) && (y==li->next->y1 || y==li->next->y2) )
|
1249
|
+
if( ((y == li->y1)? -1:1) != ((y == li->next->y1)? -1:1) )
|
1250
|
+
li->next = li->next->next;
|
1251
|
+
}
|
1252
|
+
|
1253
|
+
|
1254
|
+
//==================================================================================
|
1255
|
+
// Draws a n-points filled polygon
|
1256
|
+
//==================================================================================
|
1257
|
+
|
1258
|
+
int sge_FilledPolygonAlpha(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint32 color, Uint8 alpha)
|
1259
|
+
{
|
1260
|
+
if(n<3)
|
1261
|
+
return -1;
|
1262
|
+
|
1263
|
+
if (SDL_MUSTLOCK(dest) && _sge_lock)
|
1264
|
+
if (SDL_LockSurface(dest) < 0)
|
1265
|
+
return -2;
|
1266
|
+
|
1267
|
+
pline *line = new pline[n];
|
1268
|
+
pline_p *plist = new pline_p[n];
|
1269
|
+
|
1270
|
+
Sint16 y1,y2, x1, x2, tmp, sy;
|
1271
|
+
Sint16 ymin = y[1], ymax=y[1];
|
1272
|
+
Sint16 xmin = x[1], xmax=x[1];
|
1273
|
+
Uint16 i;
|
1274
|
+
|
1275
|
+
/* Decompose polygon into straight lines */
|
1276
|
+
for( i = 0; i < n; i++ ){
|
1277
|
+
y1 = y[i];
|
1278
|
+
x1 = x[i];
|
1279
|
+
|
1280
|
+
if( i == n-1 ){
|
1281
|
+
// Last point == First point
|
1282
|
+
y2 = y[0];
|
1283
|
+
x2 = x[0];
|
1284
|
+
}else{
|
1285
|
+
y2 = y[i+1];
|
1286
|
+
x2 = x[i+1];
|
1287
|
+
}
|
1288
|
+
|
1289
|
+
// Make sure y1 <= y2
|
1290
|
+
if( y1 > y2 ) {
|
1291
|
+
SWAP(y1,y2,tmp);
|
1292
|
+
SWAP(x1,x2,tmp);
|
1293
|
+
}
|
1294
|
+
|
1295
|
+
// Reject polygons with negative coords
|
1296
|
+
if( y1 < 0 || x1 < 0 || x2 < 0 ){
|
1297
|
+
if (SDL_MUSTLOCK(dest) && _sge_lock)
|
1298
|
+
SDL_UnlockSurface(dest);
|
1299
|
+
|
1300
|
+
delete[] line;
|
1301
|
+
delete[] plist;
|
1302
|
+
return -1;
|
1303
|
+
}
|
1304
|
+
|
1305
|
+
if( y1 < ymin )
|
1306
|
+
ymin = y1;
|
1307
|
+
if( y2 > ymax )
|
1308
|
+
ymax = y2;
|
1309
|
+
if( x1 < xmin )
|
1310
|
+
xmin = x1;
|
1311
|
+
else if( x1 > xmax )
|
1312
|
+
xmax = x1;
|
1313
|
+
if( x2 < xmin )
|
1314
|
+
xmin = x2;
|
1315
|
+
else if( x2 > xmax )
|
1316
|
+
xmax = x2;
|
1317
|
+
|
1318
|
+
//Fill structure
|
1319
|
+
line[i].y1 = y1;
|
1320
|
+
line[i].y2 = y2;
|
1321
|
+
line[i].x1 = x1;
|
1322
|
+
line[i].x2 = x2;
|
1323
|
+
|
1324
|
+
// Start x-value (fixed point)
|
1325
|
+
line[i].fx = Sint32(x1<<16);
|
1326
|
+
|
1327
|
+
// Lines step value (fixed point)
|
1328
|
+
if( y1 != y2)
|
1329
|
+
line[i].fm = Sint32((x2 - x1)<<16)/Sint32(y2 - y1);
|
1330
|
+
else
|
1331
|
+
line[i].fm = 0;
|
1332
|
+
|
1333
|
+
line[i].next = NULL;
|
1334
|
+
|
1335
|
+
// Add to list
|
1336
|
+
plist[i].p = &line[i];
|
1337
|
+
|
1338
|
+
// Draw the polygon outline (looks nicer)
|
1339
|
+
if( alpha == SDL_ALPHA_OPAQUE )
|
1340
|
+
_Line(dest,x1,y1,x2,y2,color); // Can't do this with alpha, might overlap with the filling
|
1341
|
+
}
|
1342
|
+
|
1343
|
+
/* Remove surface lock if _HLine() is to be used */
|
1344
|
+
if (SDL_MUSTLOCK(dest) && _sge_lock && alpha == SDL_ALPHA_OPAQUE)
|
1345
|
+
SDL_UnlockSurface(dest);
|
1346
|
+
|
1347
|
+
pline* list = NULL;
|
1348
|
+
pline* li = NULL; // list itterator
|
1349
|
+
|
1350
|
+
// Scan y-lines
|
1351
|
+
for( sy = ymin; sy <= ymax; sy++){
|
1352
|
+
list = get_scanline(plist, n, sy);
|
1353
|
+
|
1354
|
+
if( !list )
|
1355
|
+
continue; // nothing in list... hmmmm
|
1356
|
+
|
1357
|
+
x1 = x2 = -1;
|
1358
|
+
|
1359
|
+
// Draw horizontal lines between pairs
|
1360
|
+
for( li = list; li; li = li->next ){
|
1361
|
+
remove_dup(li, sy);
|
1362
|
+
|
1363
|
+
if( x1 < 0 )
|
1364
|
+
x1 = li->x+1;
|
1365
|
+
else if( x2 < 0 )
|
1366
|
+
x2 = li->x;
|
1367
|
+
|
1368
|
+
if( x1 >= 0 && x2 >= 0 ){
|
1369
|
+
if( x2-x1 < 0 && alpha == SDL_ALPHA_OPAQUE ){
|
1370
|
+
// Already drawn by the outline
|
1371
|
+
x1 = x2 = -1;
|
1372
|
+
continue;
|
1373
|
+
}
|
1374
|
+
|
1375
|
+
if( alpha == SDL_ALPHA_OPAQUE )
|
1376
|
+
_HLine(dest, x1, x2, sy, color);
|
1377
|
+
else
|
1378
|
+
_HLineAlpha(dest, x1-1, x2, sy, color, alpha);
|
1379
|
+
|
1380
|
+
x1 = x2 = -1;
|
1381
|
+
}
|
1382
|
+
}
|
1383
|
+
}
|
1384
|
+
|
1385
|
+
if (SDL_MUSTLOCK(dest) && _sge_lock && alpha != SDL_ALPHA_OPAQUE)
|
1386
|
+
SDL_UnlockSurface(dest);
|
1387
|
+
|
1388
|
+
delete[] line;
|
1389
|
+
delete[] plist;
|
1390
|
+
|
1391
|
+
if(_sge_update!=1){return 0;}
|
1392
|
+
|
1393
|
+
sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
|
1394
|
+
|
1395
|
+
return 0;
|
1396
|
+
}
|
1397
|
+
|
1398
|
+
int sge_FilledPolygonAlpha(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha)
|
1399
|
+
{
|
1400
|
+
return sge_FilledPolygonAlpha(dest, n, x, y, SDL_MapRGB(dest->format,r,g,b), alpha);
|
1401
|
+
}
|
1402
|
+
|
1403
|
+
int sge_FilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint32 color)
|
1404
|
+
{
|
1405
|
+
return sge_FilledPolygonAlpha(dest, n, x, y, color, SDL_ALPHA_OPAQUE);
|
1406
|
+
}
|
1407
|
+
|
1408
|
+
int sge_FilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 r, Uint8 g, Uint8 b)
|
1409
|
+
{
|
1410
|
+
return sge_FilledPolygonAlpha(dest, n, x, y, SDL_MapRGB(dest->format,r,g,b), SDL_ALPHA_OPAQUE);
|
1411
|
+
}
|
1412
|
+
|
1413
|
+
|
1414
|
+
//==================================================================================
|
1415
|
+
// Draws a n-points (AA) filled polygon
|
1416
|
+
//==================================================================================
|
1417
|
+
|
1418
|
+
int sge_AAFilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint32 color)
|
1419
|
+
{
|
1420
|
+
if(n<3)
|
1421
|
+
return -1;
|
1422
|
+
|
1423
|
+
|
1424
|
+
if (SDL_MUSTLOCK(dest) && _sge_lock)
|
1425
|
+
if (SDL_LockSurface(dest) < 0)
|
1426
|
+
return -2;
|
1427
|
+
|
1428
|
+
pline *line = new pline[n];
|
1429
|
+
pline_p *plist = new pline_p[n];
|
1430
|
+
|
1431
|
+
Sint16 y1,y2, x1, x2, tmp, sy;
|
1432
|
+
Sint16 ymin = y[1], ymax=y[1];
|
1433
|
+
Sint16 xmin = x[1], xmax=x[1];
|
1434
|
+
Uint16 i;
|
1435
|
+
|
1436
|
+
/* Decompose polygon into straight lines */
|
1437
|
+
for( i = 0; i < n; i++ ){
|
1438
|
+
y1 = y[i];
|
1439
|
+
x1 = x[i];
|
1440
|
+
|
1441
|
+
if( i == n-1 ){
|
1442
|
+
// Last point == First point
|
1443
|
+
y2 = y[0];
|
1444
|
+
x2 = x[0];
|
1445
|
+
}else{
|
1446
|
+
y2 = y[i+1];
|
1447
|
+
x2 = x[i+1];
|
1448
|
+
}
|
1449
|
+
|
1450
|
+
// Make sure y1 <= y2
|
1451
|
+
if( y1 > y2 ) {
|
1452
|
+
SWAP(y1,y2,tmp);
|
1453
|
+
SWAP(x1,x2,tmp);
|
1454
|
+
}
|
1455
|
+
|
1456
|
+
// Reject polygons with negative coords
|
1457
|
+
if( y1 < 0 || x1 < 0 || x2 < 0 ){
|
1458
|
+
if (SDL_MUSTLOCK(dest) && _sge_lock)
|
1459
|
+
SDL_UnlockSurface(dest);
|
1460
|
+
|
1461
|
+
delete[] line;
|
1462
|
+
delete[] plist;
|
1463
|
+
return -1;
|
1464
|
+
}
|
1465
|
+
|
1466
|
+
if( y1 < ymin )
|
1467
|
+
ymin = y1;
|
1468
|
+
if( y2 > ymax )
|
1469
|
+
ymax = y2;
|
1470
|
+
if( x1 < xmin )
|
1471
|
+
xmin = x1;
|
1472
|
+
else if( x1 > xmax )
|
1473
|
+
xmax = x1;
|
1474
|
+
if( x2 < xmin )
|
1475
|
+
xmin = x2;
|
1476
|
+
else if( x2 > xmax )
|
1477
|
+
xmax = x2;
|
1478
|
+
|
1479
|
+
//Fill structure
|
1480
|
+
line[i].y1 = y1;
|
1481
|
+
line[i].y2 = y2;
|
1482
|
+
line[i].x1 = x1;
|
1483
|
+
line[i].x2 = x2;
|
1484
|
+
|
1485
|
+
// Start x-value (fixed point)
|
1486
|
+
line[i].fx = Sint32(x1<<16);
|
1487
|
+
|
1488
|
+
// Lines step value (fixed point)
|
1489
|
+
if( y1 != y2)
|
1490
|
+
line[i].fm = Sint32((x2 - x1)<<16)/Sint32(y2 - y1);
|
1491
|
+
else
|
1492
|
+
line[i].fm = 0;
|
1493
|
+
|
1494
|
+
line[i].next = NULL;
|
1495
|
+
|
1496
|
+
// Add to list
|
1497
|
+
plist[i].p = &line[i];
|
1498
|
+
|
1499
|
+
// Draw AA Line
|
1500
|
+
_AALineAlpha(dest,x1,y1,x2,y2,color,SDL_ALPHA_OPAQUE);
|
1501
|
+
}
|
1502
|
+
|
1503
|
+
if (SDL_MUSTLOCK(dest) && _sge_lock)
|
1504
|
+
SDL_UnlockSurface(dest);
|
1505
|
+
|
1506
|
+
|
1507
|
+
pline* list = NULL;
|
1508
|
+
pline* li = NULL; // list itterator
|
1509
|
+
|
1510
|
+
// Scan y-lines
|
1511
|
+
for( sy = ymin; sy <= ymax; sy++){
|
1512
|
+
list = get_scanline(plist, n, sy);
|
1513
|
+
|
1514
|
+
if( !list )
|
1515
|
+
continue; // nothing in list... hmmmm
|
1516
|
+
|
1517
|
+
x1 = x2 = -1;
|
1518
|
+
|
1519
|
+
// Draw horizontal lines between pairs
|
1520
|
+
for( li = list; li; li = li->next ){
|
1521
|
+
remove_dup(li, sy);
|
1522
|
+
|
1523
|
+
if( x1 < 0 )
|
1524
|
+
x1 = li->x+1;
|
1525
|
+
else if( x2 < 0 )
|
1526
|
+
x2 = li->x;
|
1527
|
+
|
1528
|
+
if( x1 >= 0 && x2 >= 0 ){
|
1529
|
+
if( x2-x1 < 0 ){
|
1530
|
+
x1 = x2 = -1;
|
1531
|
+
continue;
|
1532
|
+
}
|
1533
|
+
|
1534
|
+
_HLine(dest, x1, x2, sy, color);
|
1535
|
+
|
1536
|
+
x1 = x2 = -1;
|
1537
|
+
}
|
1538
|
+
}
|
1539
|
+
}
|
1540
|
+
|
1541
|
+
delete[] line;
|
1542
|
+
delete[] plist;
|
1543
|
+
|
1544
|
+
if(_sge_update!=1){return 0;}
|
1545
|
+
|
1546
|
+
sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
|
1547
|
+
|
1548
|
+
return 0;
|
1549
|
+
}
|
1550
|
+
|
1551
|
+
int sge_AAFilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 r, Uint8 g, Uint8 b)
|
1552
|
+
{
|
1553
|
+
return sge_AAFilledPolygon(dest, n, x, y, SDL_MapRGB(dest->format,r,g,b));
|
1554
|
+
}
|
1555
|
+
|
1556
|
+
|
1557
|
+
//==================================================================================
|
1558
|
+
// Draws a n-points gourand shaded polygon
|
1559
|
+
//==================================================================================
|
1560
|
+
|
1561
|
+
/* faded polygon structure */
|
1562
|
+
class fpline : public pline{
|
1563
|
+
public:
|
1564
|
+
Uint8 r1, r2;
|
1565
|
+
Uint8 g1, g2;
|
1566
|
+
Uint8 b1, b2;
|
1567
|
+
|
1568
|
+
Uint32 fr, fg, fb;
|
1569
|
+
Sint32 fmr, fmg, fmb;
|
1570
|
+
|
1571
|
+
Uint8 r,g,b;
|
1572
|
+
|
1573
|
+
virtual void update(void)
|
1574
|
+
{
|
1575
|
+
x = Sint16(fx>>16);
|
1576
|
+
fx += fm;
|
1577
|
+
|
1578
|
+
r = Uint8(fr>>16);
|
1579
|
+
g = Uint8(fg>>16);
|
1580
|
+
b = Uint8(fb>>16);
|
1581
|
+
|
1582
|
+
fr += fmr;
|
1583
|
+
fg += fmg;
|
1584
|
+
fb += fmb;
|
1585
|
+
}
|
1586
|
+
};
|
1587
|
+
|
1588
|
+
int sge_FadedPolygonAlpha(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 *R, Uint8 *G, Uint8 *B, Uint8 alpha)
|
1589
|
+
{
|
1590
|
+
if(n<3)
|
1591
|
+
return -1;
|
1592
|
+
|
1593
|
+
if (SDL_MUSTLOCK(dest) && _sge_lock)
|
1594
|
+
if (SDL_LockSurface(dest) < 0)
|
1595
|
+
return -2;
|
1596
|
+
|
1597
|
+
fpline *line = new fpline[n];
|
1598
|
+
pline_p *plist = new pline_p[n];
|
1599
|
+
|
1600
|
+
Sint16 y1,y2, x1, x2, tmp, sy;
|
1601
|
+
Sint16 ymin = y[1], ymax=y[1];
|
1602
|
+
Sint16 xmin = x[1], xmax=x[1];
|
1603
|
+
Uint16 i;
|
1604
|
+
Uint8 r1=0, g1=0, b1=0, r2=0, g2=0, b2=0, t;
|
1605
|
+
|
1606
|
+
// Decompose polygon into straight lines
|
1607
|
+
for( i = 0; i < n; i++ ){
|
1608
|
+
y1 = y[i];
|
1609
|
+
x1 = x[i];
|
1610
|
+
r1 = R[i];
|
1611
|
+
g1 = G[i];
|
1612
|
+
b1 = B[i];
|
1613
|
+
|
1614
|
+
if( i == n-1 ){
|
1615
|
+
// Last point == First point
|
1616
|
+
y2 = y[0];
|
1617
|
+
x2 = x[0];
|
1618
|
+
r2 = R[0];
|
1619
|
+
g2 = G[0];
|
1620
|
+
b2 = B[0];
|
1621
|
+
}else{
|
1622
|
+
y2 = y[i+1];
|
1623
|
+
x2 = x[i+1];
|
1624
|
+
r2 = R[i+1];
|
1625
|
+
g2 = G[i+1];
|
1626
|
+
b2 = B[i+1];
|
1627
|
+
}
|
1628
|
+
|
1629
|
+
// Make sure y1 <= y2
|
1630
|
+
if( y1 > y2 ) {
|
1631
|
+
SWAP(y1,y2,tmp);
|
1632
|
+
SWAP(x1,x2,tmp);
|
1633
|
+
SWAP(r1,r2,t);
|
1634
|
+
SWAP(g1,g2,t);
|
1635
|
+
SWAP(b1,b2,t);
|
1636
|
+
}
|
1637
|
+
|
1638
|
+
// Reject polygons with negative coords
|
1639
|
+
if( y1 < 0 || x1 < 0 || x2 < 0 ){
|
1640
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
1641
|
+
SDL_UnlockSurface(dest);
|
1642
|
+
|
1643
|
+
delete[] line;
|
1644
|
+
delete[] plist;
|
1645
|
+
return -1;
|
1646
|
+
}
|
1647
|
+
|
1648
|
+
if( y1 < ymin )
|
1649
|
+
ymin = y1;
|
1650
|
+
if( y2 > ymax )
|
1651
|
+
ymax = y2;
|
1652
|
+
if( x1 < xmin )
|
1653
|
+
xmin = x1;
|
1654
|
+
else if( x1 > xmax )
|
1655
|
+
xmax = x1;
|
1656
|
+
if( x2 < xmin )
|
1657
|
+
xmin = x2;
|
1658
|
+
else if( x2 > xmax )
|
1659
|
+
xmax = x2;
|
1660
|
+
|
1661
|
+
//Fill structure
|
1662
|
+
line[i].y1 = y1;
|
1663
|
+
line[i].y2 = y2;
|
1664
|
+
line[i].x1 = x1;
|
1665
|
+
line[i].x2 = x2;
|
1666
|
+
line[i].r1 = r1;
|
1667
|
+
line[i].g1 = g1;
|
1668
|
+
line[i].b1 = b1;
|
1669
|
+
line[i].r2 = r2;
|
1670
|
+
line[i].g2 = g2;
|
1671
|
+
line[i].b2 = b2;
|
1672
|
+
|
1673
|
+
// Start x-value (fixed point)
|
1674
|
+
line[i].fx = Sint32(x1<<16);
|
1675
|
+
|
1676
|
+
line[i].fr = Uint32(r1<<16);
|
1677
|
+
line[i].fg = Uint32(g1<<16);
|
1678
|
+
line[i].fb = Uint32(b1<<16);
|
1679
|
+
|
1680
|
+
// Lines step value (fixed point)
|
1681
|
+
if( y1 != y2){
|
1682
|
+
line[i].fm = Sint32((x2 - x1)<<16)/Sint32(y2 - y1);
|
1683
|
+
|
1684
|
+
line[i].fmr = Sint32((r2 - r1)<<16)/Sint32(y2 - y1);
|
1685
|
+
line[i].fmg = Sint32((g2 - g1)<<16)/Sint32(y2 - y1);
|
1686
|
+
line[i].fmb = Sint32((b2 - b1)<<16)/Sint32(y2 - y1);
|
1687
|
+
}else{
|
1688
|
+
line[i].fm = 0;
|
1689
|
+
line[i].fmr = 0;
|
1690
|
+
line[i].fmg = 0;
|
1691
|
+
line[i].fmb = 0;
|
1692
|
+
}
|
1693
|
+
|
1694
|
+
line[i].next = NULL;
|
1695
|
+
|
1696
|
+
// Add to list
|
1697
|
+
plist[i].p = &line[i];
|
1698
|
+
|
1699
|
+
// Draw the polygon outline (looks nicer)
|
1700
|
+
if( alpha == SDL_ALPHA_OPAQUE )
|
1701
|
+
sge_DomcLine(dest,x1,y1,x2,y2,r1,g1,b1,r2,g2,b2, _PutPixel); // Can't do this with alpha, might overlap with the filling
|
1702
|
+
}
|
1703
|
+
|
1704
|
+
fpline* list = NULL;
|
1705
|
+
fpline* li = NULL; // list itterator
|
1706
|
+
|
1707
|
+
// Scan y-lines
|
1708
|
+
for( sy = ymin; sy <= ymax; sy++){
|
1709
|
+
list = (fpline *)get_scanline(plist, n, sy);
|
1710
|
+
|
1711
|
+
if( !list )
|
1712
|
+
continue; // nothing in list... hmmmm
|
1713
|
+
|
1714
|
+
x1 = x2 = -1;
|
1715
|
+
|
1716
|
+
// Draw horizontal lines between pairs
|
1717
|
+
for( li = list; li; li = (fpline *)li->next ){
|
1718
|
+
remove_dup(li, sy);
|
1719
|
+
|
1720
|
+
if( x1 < 0 ){
|
1721
|
+
x1 = li->x+1;
|
1722
|
+
r1 = li->r;
|
1723
|
+
g1 = li->g;
|
1724
|
+
b1 = li->b;
|
1725
|
+
}else if( x2 < 0 ){
|
1726
|
+
x2 = li->x;
|
1727
|
+
r2 = li->r;
|
1728
|
+
g2 = li->g;
|
1729
|
+
b2 = li->b;
|
1730
|
+
}
|
1731
|
+
|
1732
|
+
if( x1 >= 0 && x2 >= 0 ){
|
1733
|
+
if( x2-x1 < 0 && alpha == SDL_ALPHA_OPAQUE){
|
1734
|
+
x1 = x2 = -1;
|
1735
|
+
continue;
|
1736
|
+
}
|
1737
|
+
|
1738
|
+
if( alpha == SDL_ALPHA_OPAQUE )
|
1739
|
+
_FadedLine(dest, x1, x2, sy, r1, g1, b1, r2, g2, b2);
|
1740
|
+
else{
|
1741
|
+
_sge_alpha_hack = alpha;
|
1742
|
+
sge_DomcLine(dest, x1-1, sy, x2, sy, r1, g1, b1, r2, g2, b2, callback_alpha_hack);
|
1743
|
+
}
|
1744
|
+
|
1745
|
+
x1 = x2 = -1;
|
1746
|
+
}
|
1747
|
+
}
|
1748
|
+
}
|
1749
|
+
|
1750
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
1751
|
+
SDL_UnlockSurface(dest);
|
1752
|
+
|
1753
|
+
delete[] line;
|
1754
|
+
delete[] plist;
|
1755
|
+
|
1756
|
+
if(_sge_update!=1){return 0;}
|
1757
|
+
|
1758
|
+
sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
|
1759
|
+
|
1760
|
+
return 0;
|
1761
|
+
}
|
1762
|
+
|
1763
|
+
int sge_FadedPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 *R, Uint8 *G, Uint8 *B)
|
1764
|
+
{
|
1765
|
+
return sge_FadedPolygonAlpha(dest, n, x, y, R, G, B, SDL_ALPHA_OPAQUE);
|
1766
|
+
}
|
1767
|
+
|
1768
|
+
|
1769
|
+
//==================================================================================
|
1770
|
+
// Draws a n-points (AA) gourand shaded polygon
|
1771
|
+
//==================================================================================
|
1772
|
+
int sge_AAFadedPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 *R, Uint8 *G, Uint8 *B)
|
1773
|
+
{
|
1774
|
+
if(n<3)
|
1775
|
+
return -1;
|
1776
|
+
|
1777
|
+
if (SDL_MUSTLOCK(dest) && _sge_lock)
|
1778
|
+
if (SDL_LockSurface(dest) < 0)
|
1779
|
+
return -2;
|
1780
|
+
|
1781
|
+
fpline *line = new fpline[n];
|
1782
|
+
pline_p *plist = new pline_p[n];
|
1783
|
+
|
1784
|
+
Sint16 y1,y2, x1, x2, tmp, sy;
|
1785
|
+
Sint16 ymin = y[1], ymax=y[1];
|
1786
|
+
Sint16 xmin = x[1], xmax=x[1];
|
1787
|
+
Uint16 i;
|
1788
|
+
Uint8 r1=0, g1=0, b1=0, r2=0, g2=0, b2=0, t;
|
1789
|
+
|
1790
|
+
// Decompose polygon into straight lines
|
1791
|
+
for( i = 0; i < n; i++ ){
|
1792
|
+
y1 = y[i];
|
1793
|
+
x1 = x[i];
|
1794
|
+
r1 = R[i];
|
1795
|
+
g1 = G[i];
|
1796
|
+
b1 = B[i];
|
1797
|
+
|
1798
|
+
if( i == n-1 ){
|
1799
|
+
// Last point == First point
|
1800
|
+
y2 = y[0];
|
1801
|
+
x2 = x[0];
|
1802
|
+
r2 = R[0];
|
1803
|
+
g2 = G[0];
|
1804
|
+
b2 = B[0];
|
1805
|
+
}else{
|
1806
|
+
y2 = y[i+1];
|
1807
|
+
x2 = x[i+1];
|
1808
|
+
r2 = R[i+1];
|
1809
|
+
g2 = G[i+1];
|
1810
|
+
b2 = B[i+1];
|
1811
|
+
}
|
1812
|
+
|
1813
|
+
// Make sure y1 <= y2
|
1814
|
+
if( y1 > y2 ) {
|
1815
|
+
SWAP(y1,y2,tmp);
|
1816
|
+
SWAP(x1,x2,tmp);
|
1817
|
+
SWAP(r1,r2,t);
|
1818
|
+
SWAP(g1,g2,t);
|
1819
|
+
SWAP(b1,b2,t);
|
1820
|
+
}
|
1821
|
+
|
1822
|
+
// Reject polygons with negative coords
|
1823
|
+
if( y1 < 0 || x1 < 0 || x2 < 0 ){
|
1824
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
1825
|
+
SDL_UnlockSurface(dest);
|
1826
|
+
|
1827
|
+
delete[] line;
|
1828
|
+
delete[] plist;
|
1829
|
+
return -1;
|
1830
|
+
}
|
1831
|
+
|
1832
|
+
if( y1 < ymin )
|
1833
|
+
ymin = y1;
|
1834
|
+
if( y2 > ymax )
|
1835
|
+
ymax = y2;
|
1836
|
+
if( x1 < xmin )
|
1837
|
+
xmin = x1;
|
1838
|
+
else if( x1 > xmax )
|
1839
|
+
xmax = x1;
|
1840
|
+
if( x2 < xmin )
|
1841
|
+
xmin = x2;
|
1842
|
+
else if( x2 > xmax )
|
1843
|
+
xmax = x2;
|
1844
|
+
|
1845
|
+
//Fill structure
|
1846
|
+
line[i].y1 = y1;
|
1847
|
+
line[i].y2 = y2;
|
1848
|
+
line[i].x1 = x1;
|
1849
|
+
line[i].x2 = x2;
|
1850
|
+
line[i].r1 = r1;
|
1851
|
+
line[i].g1 = g1;
|
1852
|
+
line[i].b1 = b1;
|
1853
|
+
line[i].r2 = r2;
|
1854
|
+
line[i].g2 = g2;
|
1855
|
+
line[i].b2 = b2;
|
1856
|
+
|
1857
|
+
// Start x-value (fixed point)
|
1858
|
+
line[i].fx = Sint32(x1<<16);
|
1859
|
+
|
1860
|
+
line[i].fr = Uint32(r1<<16);
|
1861
|
+
line[i].fg = Uint32(g1<<16);
|
1862
|
+
line[i].fb = Uint32(b1<<16);
|
1863
|
+
|
1864
|
+
// Lines step value (fixed point)
|
1865
|
+
if( y1 != y2){
|
1866
|
+
line[i].fm = Sint32((x2 - x1)<<16)/Sint32(y2 - y1);
|
1867
|
+
|
1868
|
+
line[i].fmr = Sint32((r2 - r1)<<16)/Sint32(y2 - y1);
|
1869
|
+
line[i].fmg = Sint32((g2 - g1)<<16)/Sint32(y2 - y1);
|
1870
|
+
line[i].fmb = Sint32((b2 - b1)<<16)/Sint32(y2 - y1);
|
1871
|
+
}else{
|
1872
|
+
line[i].fm = 0;
|
1873
|
+
line[i].fmr = 0;
|
1874
|
+
line[i].fmg = 0;
|
1875
|
+
line[i].fmb = 0;
|
1876
|
+
}
|
1877
|
+
|
1878
|
+
line[i].next = NULL;
|
1879
|
+
|
1880
|
+
// Add to list
|
1881
|
+
plist[i].p = &line[i];
|
1882
|
+
|
1883
|
+
// Draw the polygon outline (AA)
|
1884
|
+
_AAmcLineAlpha(dest,x1,y1,x2,y2,r1,g1,b1,r2,g2,b2,SDL_ALPHA_OPAQUE);
|
1885
|
+
}
|
1886
|
+
|
1887
|
+
fpline* list = NULL;
|
1888
|
+
fpline* li = NULL; // list itterator
|
1889
|
+
|
1890
|
+
// Scan y-lines
|
1891
|
+
for( sy = ymin; sy <= ymax; sy++){
|
1892
|
+
list = (fpline *)get_scanline(plist, n, sy);
|
1893
|
+
|
1894
|
+
if( !list )
|
1895
|
+
continue; // nothing in list... hmmmm
|
1896
|
+
|
1897
|
+
x1 = x2 = -1;
|
1898
|
+
|
1899
|
+
// Draw horizontal lines between pairs
|
1900
|
+
for( li = list; li; li = (fpline *)li->next ){
|
1901
|
+
remove_dup(li, sy);
|
1902
|
+
|
1903
|
+
if( x1 < 0 ){
|
1904
|
+
x1 = li->x+1;
|
1905
|
+
r1 = li->r;
|
1906
|
+
g1 = li->g;
|
1907
|
+
b1 = li->b;
|
1908
|
+
}else if( x2 < 0 ){
|
1909
|
+
x2 = li->x;
|
1910
|
+
r2 = li->r;
|
1911
|
+
g2 = li->g;
|
1912
|
+
b2 = li->b;
|
1913
|
+
}
|
1914
|
+
|
1915
|
+
if( x1 >= 0 && x2 >= 0 ){
|
1916
|
+
if( x2-x1 < 0 ){
|
1917
|
+
x1 = x2 = -1;
|
1918
|
+
continue;
|
1919
|
+
}
|
1920
|
+
|
1921
|
+
_FadedLine(dest, x1, x2, sy, r1, g1, b1, r2, g2, b2);
|
1922
|
+
|
1923
|
+
x1 = x2 = -1;
|
1924
|
+
}
|
1925
|
+
}
|
1926
|
+
}
|
1927
|
+
|
1928
|
+
if ( SDL_MUSTLOCK(dest) && _sge_lock )
|
1929
|
+
SDL_UnlockSurface(dest);
|
1930
|
+
|
1931
|
+
delete[] line;
|
1932
|
+
delete[] plist;
|
1933
|
+
|
1934
|
+
if(_sge_update!=1){return 0;}
|
1935
|
+
|
1936
|
+
sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
|
1937
|
+
|
1938
|
+
return 0;
|
1939
|
+
}
|