rubysdl 2.1.2 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/NEWS.en +8 -0
  2. data/NEWS.ja +8 -0
  3. data/README.en +22 -15
  4. data/README.ja +31 -20
  5. data/depend +2 -0
  6. data/doc-en/event.rsd +3 -0
  7. data/doc-en/time.rsd +1 -1
  8. data/doc-en/video.rsd +8 -8
  9. data/doc.txt +32 -0
  10. data/doc/event.rsd +5 -0
  11. data/doc/opengl.rsd +160 -0
  12. data/doc/rsd.rb +4 -3
  13. data/doc/time.rsd +1 -1
  14. data/doc/video.rsd +8 -8
  15. data/extconf.rb +30 -15
  16. data/lib/sdl.rb +2 -1
  17. data/lib/sdl1_compatible.rb +20 -0
  18. data/mkpkg.sh +28 -0
  19. data/rubysdl.gemspec +21 -0
  20. data/rubysdl.h +1 -0
  21. data/rubysdl_cdrom.c +0 -10
  22. data/rubysdl_event.c +30 -11
  23. data/rubysdl_event_key.c +0 -5
  24. data/rubysdl_image.c +2 -2
  25. data/rubysdl_joystick.c +0 -18
  26. data/rubysdl_kanji.c +0 -5
  27. data/rubysdl_main.c +0 -2
  28. data/rubysdl_mixer.c +2 -18
  29. data/rubysdl_mouse.c +0 -4
  30. data/rubysdl_rwops.c +4 -0
  31. data/rubysdl_sdlskk.c +0 -3
  32. data/rubysdl_sge_video.c +0 -14
  33. data/rubysdl_smpeg.c +0 -1
  34. data/rubysdl_time.c +0 -10
  35. data/rubysdl_ttf.c +0 -3
  36. data/rubysdl_video.c +2 -30
  37. data/rubysdl_wm.c +0 -5
  38. data/sample/caption.rb +21 -0
  39. data/sge/INSTALL +72 -0
  40. data/sge/LICENSE +504 -0
  41. data/sge/Makefile +83 -0
  42. data/sge/Makefile.conf +63 -0
  43. data/sge/README +219 -0
  44. data/sge/Todo +7 -0
  45. data/sge/WhatsNew +224 -0
  46. data/sge/sge.h +31 -0
  47. data/sge/sge_blib.cpp +1939 -0
  48. data/sge/sge_blib.h +68 -0
  49. data/sge/sge_bm_text.cpp +451 -0
  50. data/sge/sge_bm_text.h +71 -0
  51. data/sge/sge_collision.cpp +388 -0
  52. data/sge/sge_collision.h +54 -0
  53. data/sge/sge_config.h +6 -0
  54. data/sge/sge_internal.h +152 -0
  55. data/sge/sge_misc.cpp +92 -0
  56. data/sge/sge_misc.h +37 -0
  57. data/sge/sge_primitives.cpp +2516 -0
  58. data/sge/sge_primitives.h +111 -0
  59. data/sge/sge_rotation.cpp +683 -0
  60. data/sge/sge_rotation.h +46 -0
  61. data/sge/sge_shape.cpp +762 -0
  62. data/sge/sge_shape.h +365 -0
  63. data/sge/sge_surface.cpp +1090 -0
  64. data/sge/sge_surface.h +100 -0
  65. data/sge/sge_textpp.cpp +785 -0
  66. data/sge/sge_textpp.h +270 -0
  67. data/sge/sge_tt_text.cpp +1456 -0
  68. data/sge/sge_tt_text.h +114 -0
  69. data/utils/buildtest.sh +29 -0
  70. data/win32/README.en.win32 +72 -0
  71. data/win32/README.ja.win32 +80 -0
  72. data/win32/install_rubysdl.rb +30 -0
  73. data/win32/mkpkg.sh +72 -0
  74. metadata +136 -113
  75. data/rubysdl_ref.en.html +0 -5879
  76. data/rubysdl_ref.en.rd +0 -6601
  77. data/rubysdl_ref.html +0 -6194
  78. data/rubysdl_ref.rd +0 -6950
@@ -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
+ }