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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/History.rdoc +30 -0
  5. data/Manifest.txt +39 -7
  6. data/README.rdoc +48 -4
  7. data/Rakefile +8 -2
  8. data/examples/boid.rb +9 -18
  9. data/examples/bounce.rb +15 -23
  10. data/examples/canvas.rb +75 -0
  11. data/examples/collision.rb +6 -6
  12. data/examples/demo.rb +5 -7
  13. data/examples/editor.rb +12 -9
  14. data/examples/fluid.rb +2 -3
  15. data/examples/fluid2.rb +1 -1
  16. data/examples/{lito2.rb → gol.rb} +0 -0
  17. data/examples/{zenspider4.rb → gol2.rb} +0 -0
  18. data/examples/logo.rb +4 -7
  19. data/examples/maze.rb +136 -0
  20. data/examples/tank.rb +10 -11
  21. data/examples/tank2.rb +12 -17
  22. data/examples/targeting.rb +1 -1
  23. data/examples/vants.rb +1 -1
  24. data/examples/walker.rb +3 -12
  25. data/examples/walker2.rb +197 -0
  26. data/examples/zombies.rb +31 -35
  27. data/ext/sdl/extconf.rb +31 -0
  28. data/ext/sdl/sdl.c +1067 -0
  29. data/ext/sdl/sge/INSTALL +72 -0
  30. data/ext/sdl/sge/LICENSE +504 -0
  31. data/ext/sdl/sge/Makefile +83 -0
  32. data/ext/sdl/sge/Makefile.conf +63 -0
  33. data/ext/sdl/sge/README +219 -0
  34. data/ext/sdl/sge/Todo +7 -0
  35. data/ext/sdl/sge/WhatsNew +224 -0
  36. data/ext/sdl/sge/sge.h +31 -0
  37. data/ext/sdl/sge/sge_blib.cpp +1939 -0
  38. data/ext/sdl/sge/sge_blib.h +68 -0
  39. data/ext/sdl/sge/sge_bm_text.cpp +451 -0
  40. data/ext/sdl/sge/sge_bm_text.h +71 -0
  41. data/ext/sdl/sge/sge_collision.cpp +388 -0
  42. data/ext/sdl/sge/sge_collision.h +54 -0
  43. data/ext/sdl/sge/sge_config.h +6 -0
  44. data/ext/sdl/sge/sge_internal.h +152 -0
  45. data/ext/sdl/sge/sge_misc.cpp +92 -0
  46. data/ext/sdl/sge/sge_misc.h +37 -0
  47. data/ext/sdl/sge/sge_primitives.cpp +2516 -0
  48. data/ext/sdl/sge/sge_primitives.h +111 -0
  49. data/ext/sdl/sge/sge_rotation.cpp +683 -0
  50. data/ext/sdl/sge/sge_rotation.h +46 -0
  51. data/ext/sdl/sge/sge_shape.cpp +762 -0
  52. data/ext/sdl/sge/sge_shape.h +365 -0
  53. data/ext/sdl/sge/sge_surface.cpp +1090 -0
  54. data/ext/sdl/sge/sge_surface.h +100 -0
  55. data/ext/sdl/sge/sge_textpp.cpp +785 -0
  56. data/ext/sdl/sge/sge_textpp.h +270 -0
  57. data/ext/sdl/sge/sge_tt_text.cpp +1456 -0
  58. data/ext/sdl/sge/sge_tt_text.h +114 -0
  59. data/graphics_setup.sh +26 -0
  60. data/lib/graphics.rb +1 -1
  61. data/lib/graphics/body.rb +50 -3
  62. data/lib/graphics/extensions.rb +13 -7
  63. data/lib/graphics/simulation.rb +126 -46
  64. data/test/test_graphics.rb +52 -12
  65. data/test/test_sdl.rb +1 -0
  66. metadata +54 -23
  67. metadata.gz.sig +0 -0
  68. data/.gemtest +0 -0
  69. data/examples/lito.rb +0 -108
  70. data/examples/zenspider1.rb +0 -93
  71. data/examples/zenspider2.rb +0 -123
  72. data/examples/zenspider3.rb +0 -104
  73. data/rubysdl_setup.sh +0 -34
@@ -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
+ }