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,54 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * Collision routines (header)
4
+ *
5
+ * Started 000625
6
+ *
7
+ * License: LGPL v2+ (see the file LICENSE)
8
+ * (c)1999-2003 Anders Lindstr�m
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
+ #ifndef sge_collision_H
19
+ #define sge_collision_H
20
+
21
+ #include "SDL.h"
22
+ #include "sge_internal.h"
23
+
24
+ /* The collision struct */
25
+ typedef struct
26
+ {
27
+ Uint8 *map;
28
+ Uint16 w,h;
29
+ } sge_cdata;
30
+
31
+ #ifdef _SGE_C
32
+ extern "C" {
33
+ #endif
34
+ DECLSPEC sge_cdata *sge_make_cmap(SDL_Surface *img);
35
+ DECLSPEC int sge_bbcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2);
36
+ DECLSPEC int _sge_bbcheck(Sint16 x1,Sint16 y1,Sint16 w1,Sint16 h1, Sint16 x2,Sint16 y2,Sint16 w2,Sint16 h2);
37
+ DECLSPEC int _sge_cmcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2);
38
+ DECLSPEC int sge_cmcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2);
39
+ DECLSPEC Sint16 sge_get_cx(void);
40
+ DECLSPEC Sint16 sge_get_cy(void);
41
+ DECLSPEC void sge_destroy_cmap(sge_cdata *cd);
42
+ DECLSPEC void sge_unset_cdata(sge_cdata *cd, Sint16 x, Sint16 y, Sint16 w, Sint16 h);
43
+ DECLSPEC void sge_set_cdata(sge_cdata *cd, Sint16 x, Sint16 y, Sint16 w, Sint16 h);
44
+ #ifdef _SGE_C
45
+ }
46
+ #endif
47
+
48
+ #ifndef _SGE_NO_CLASSES
49
+ class DECLSPEC sge_shape;
50
+ DECLSPEC int sge_bbcheck_shape(sge_shape *shape1, sge_shape *shape2);
51
+ #endif /* _SGE_NO_CLASSES */
52
+
53
+
54
+ #endif /* sge_collision_H */
@@ -0,0 +1,6 @@
1
+ /* SGE Config header (generated automatically) */
2
+ #define SGE_VER 030809
3
+ #define _SGE_C_AND_CPP
4
+ #define _SGE_HAVE_IMG
5
+ #define _SGE_NOTTF
6
+
@@ -0,0 +1,152 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * SGE internal header
4
+ *
5
+ * Started 000627
6
+ *
7
+ * License: LGPL v2+ (see the file LICENSE)
8
+ * (c)2000-2003 Anders Lindstr�m
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
+ #ifndef sge_internal_H
19
+ #define sge_internal_H
20
+
21
+ /* This header is included in all sge_*.h files */
22
+
23
+ #include "sge_config.h"
24
+
25
+ /*
26
+ * C compatibility
27
+ * Thanks to Ohbayashi Ippei (ohai@kmc.gr.jp) for this clever hack!
28
+ */
29
+ #ifdef _SGE_C_AND_CPP
30
+ #ifdef __cplusplus
31
+ #define _SGE_C /* use extern "C" on base functions */
32
+ #else
33
+ #define sge_C_ONLY /* remove overloaded functions */
34
+ #define _SGE_NO_CLASSES /* no C++ classes */
35
+ #endif
36
+ #endif
37
+
38
+
39
+ /*
40
+ * This is traditional
41
+ */
42
+ #ifndef PI
43
+ #define PI 3.1414926535
44
+ #endif
45
+
46
+
47
+ /*
48
+ * Bit flags
49
+ */
50
+ #define SGE_FLAG0 0x00
51
+ #define SGE_FLAG1 0x01
52
+ #define SGE_FLAG2 0x02
53
+ #define SGE_FLAG3 0x04
54
+ #define SGE_FLAG4 0x08
55
+ #define SGE_FLAG5 0x10
56
+ #define SGE_FLAG6 0x20
57
+ #define SGE_FLAG7 0x40
58
+ #define SGE_FLAG8 0x80
59
+
60
+
61
+ /*
62
+ * Define the right alpha values
63
+ * (they were fliped in SDL 1.1.5+)
64
+ */
65
+ #ifndef SDL_ALPHA_OPAQUE
66
+ #define SDL_ALPHA_OPAQUE 0
67
+ #endif
68
+ #ifndef SDL_ALPHA_TRANSPARENT
69
+ #define SDL_ALPHA_TRANSPARENT 255
70
+ #endif
71
+
72
+
73
+ /*
74
+ * Older versions of SDL doesn't have SDL_VERSIONNUM
75
+ */
76
+ #ifndef SDL_VERSIONNUM
77
+ #define SDL_VERSIONNUM(X, Y, Z) \
78
+ (X)*1000 + (Y)*100 + (Z)
79
+ #endif
80
+
81
+
82
+ /*
83
+ * Older versions of SDL doesn't have SDL_CreateRGBSurface
84
+ */
85
+ #ifndef SDL_AllocSurface
86
+ #define SDL_CreateRGBSurface SDL_AllocSurface
87
+ #endif
88
+
89
+
90
+ /*
91
+ * Macro to get clipping
92
+ */
93
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \
94
+ SDL_VERSIONNUM(1, 1, 5)
95
+ #define sge_clip_xmin(pnt) pnt->clip_rect.x
96
+ #define sge_clip_xmax(pnt) pnt->clip_rect.x + pnt->clip_rect.w-1
97
+ #define sge_clip_ymin(pnt) pnt->clip_rect.y
98
+ #define sge_clip_ymax(pnt) pnt->clip_rect.y + pnt->clip_rect.h-1
99
+ #else
100
+ #define sge_clip_xmin(pnt) pnt->clip_minx
101
+ #define sge_clip_xmax(pnt) pnt->clip_maxx
102
+ #define sge_clip_ymin(pnt) pnt->clip_miny
103
+ #define sge_clip_ymax(pnt) pnt->clip_maxy
104
+ #endif
105
+
106
+
107
+ /*
108
+ * Macro to get the smallest bounding box from two (SDL_Rect) rectangles
109
+ */
110
+ #define sge_RectUnion(dst_rect, rect1, rect2)\
111
+ dst_rect.x = (rect1.x < rect2.x)? rect1.x:rect2.x;\
112
+ dst_rect.y = (rect1.y < rect2.y)? rect1.y:rect2.y;\
113
+ dst_rect.w = (rect1.x + rect1.w > rect2.x + rect2.w)? rect1.x + rect1.w - dst_rect.x : rect2.x + rect2.w - dst_rect.x;\
114
+ dst_rect.h = (rect1.y + rect1.h > rect2.y + rect2.h)? rect1.y + rect1.h - dst_rect.y : rect2.y + rect2.h - dst_rect.y;
115
+
116
+
117
+ /*
118
+ * We need to use alpha sometimes but older versions of SDL doesn't have
119
+ * alpha support.
120
+ */
121
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \
122
+ SDL_VERSIONNUM(1, 1, 5)
123
+ #define sge_MapRGBA SDL_MapRGBA
124
+ #define sge_GetRGBA SDL_GetRGBA
125
+ #else
126
+ #define sge_MapRGBA(fmt, r, g, b, a) SDL_MapRGB(fmt, r, g, b)
127
+ #define sge_GetRGBA(pixel, fmt, r, g, b, a) SDL_GetRGBA(pixel, fmt, r, g, b)
128
+ #endif
129
+
130
+
131
+ /*
132
+ * Some compilers use a special export keyword
133
+ * Thanks to Seung Chan Lim (limsc@maya.com or slim@djslim.com) to pointing this out
134
+ * (From SDL)
135
+ */
136
+ #ifndef DECLSPEC
137
+ #ifdef __BEOS__
138
+ #if defined(__GNUC__)
139
+ #define DECLSPEC __declspec(dllexport)
140
+ #else
141
+ #define DECLSPEC __declspec(export)
142
+ #endif
143
+ #else
144
+ #ifdef WIN32
145
+ #define DECLSPEC __declspec(dllexport)
146
+ #else
147
+ #define DECLSPEC
148
+ #endif
149
+ #endif
150
+ #endif
151
+
152
+ #endif /* sge_internal_H */
@@ -0,0 +1,92 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * Misc functions
4
+ *
5
+ * Started 990819
6
+ *
7
+ * License: LGPL v2+ (see the file LICENSE)
8
+ * (c)1999-2003 Anders Lindstr�m
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
+ #include "SDL.h"
19
+ #include <stdlib.h>
20
+ #include <stdio.h>
21
+ #include <time.h>
22
+ #include <math.h>
23
+ #include "sge_misc.h"
24
+
25
+
26
+ Uint32 delay_res=10;
27
+
28
+ //==================================================================================
29
+ // Returns a random integer between min and max
30
+ //==================================================================================
31
+ int sge_Random(int min, int max)
32
+ {
33
+ return min+(rand()%(max-min+1));
34
+ }
35
+
36
+
37
+ //==================================================================================
38
+ // Seed the random number generator with a number from the system clock.
39
+ // Should be called once before the first use of sge_Random.
40
+ //==================================================================================
41
+ void sge_Randomize(void)
42
+ {
43
+ srand(time(NULL));
44
+ }
45
+
46
+
47
+ //==================================================================================
48
+ // Test the resolution of SDL_Delay()
49
+ //==================================================================================
50
+ Uint32 sge_CalibrateDelay(void)
51
+ {
52
+ SDL_Delay(10);
53
+ delay_res=SDL_GetTicks();
54
+ SDL_Delay(1);
55
+ delay_res=SDL_GetTicks()-delay_res;
56
+
57
+ return delay_res;
58
+ }
59
+
60
+
61
+ //==================================================================================
62
+ // Get the resolution of SDL_Delay()
63
+ //==================================================================================
64
+ Uint32 sge_DelayRes(void)
65
+ {
66
+ return delay_res;
67
+ }
68
+
69
+
70
+ //==================================================================================
71
+ // Delay 'ticks' ms.
72
+ // Tries to burn time in SDL_Delay() if possible
73
+ // Returns the exact delay time
74
+ //==================================================================================
75
+ Uint32 sge_Delay(Uint32 ticks)
76
+ {
77
+ Uint32 start = SDL_GetTicks();
78
+ Sint32 time_left = (Sint32)ticks;
79
+ Uint32 tmp;
80
+
81
+ if(ticks >= delay_res){
82
+ tmp=ticks-(ticks%delay_res);
83
+ SDL_Delay(tmp);
84
+ time_left=(Sint32)(ticks-(SDL_GetTicks()-start)); //Possible error for large ticks... nah
85
+ }
86
+
87
+ while(time_left>0){
88
+ time_left=ticks-(SDL_GetTicks()-start);
89
+ }
90
+
91
+ return SDL_GetTicks()-start;
92
+ }
@@ -0,0 +1,37 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * Misc functions (header)
4
+ *
5
+ * Started 990819
6
+ *
7
+ * License: LGPL v2+ (see the file LICENSE)
8
+ * (c)1999-2003 Anders Lindstr�m
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
+ #ifndef sge_misc_H
19
+ #define sge_misc_H
20
+
21
+ #include "SDL.h"
22
+ #include "sge_internal.h"
23
+
24
+ #ifdef _SGE_C
25
+ extern "C" {
26
+ #endif
27
+ DECLSPEC int sge_Random(int min, int max);
28
+ DECLSPEC void sge_Randomize(void);
29
+
30
+ DECLSPEC Uint32 sge_CalibrateDelay(void);
31
+ DECLSPEC Uint32 sge_DelayRes(void);
32
+ DECLSPEC Uint32 sge_Delay(Uint32 ticks);
33
+ #ifdef _SGE_C
34
+ }
35
+ #endif
36
+
37
+ #endif /* sge_misc_H */
@@ -0,0 +1,2516 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * Drawing primitives
4
+ *
5
+ * Started 990815 (split from sge_draw 010611)
6
+ *
7
+ * License: LGPL v2+ (see the file LICENSE)
8
+ * (c)1999-2003 Anders Lindstr�m
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
+ * Some of this code is taken from the "Introduction to SDL" and
20
+ * John Garrison's PowerPak
21
+ */
22
+
23
+ #include "SDL.h"
24
+ #include <math.h>
25
+ #include <string.h>
26
+ #include <stdarg.h>
27
+ #include <stdlib.h>
28
+ #include "sge_primitives.h"
29
+ #include "sge_surface.h"
30
+
31
+
32
+ /* Globals used for sge_Update/sge_Lock (defined in sge_surface) */
33
+ extern Uint8 _sge_update;
34
+ extern Uint8 _sge_lock;
35
+
36
+ #define SWAP(x,y,temp) temp=x;x=y;y=temp
37
+
38
+ /**********************************************************************************/
39
+ /** Line functions **/
40
+ /**********************************************************************************/
41
+
42
+ //==================================================================================
43
+ // Internal draw horizontal line
44
+ //==================================================================================
45
+ void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
46
+ {
47
+ if(x1>x2){Sint16 tmp=x1; x1=x2; x2=tmp;}
48
+
49
+ //Do the clipping
50
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
51
+ SDL_VERSIONNUM(1, 1, 5)
52
+ if(y<Surface->clip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2<Surface->clip_minx)
53
+ return;
54
+ if(x1<Surface->clip_minx)
55
+ x1=Surface->clip_minx;
56
+ if(x2>Surface->clip_maxx)
57
+ x2=Surface->clip_maxx;
58
+ #endif
59
+
60
+ SDL_Rect l;
61
+ l.x=x1; l.y=y; l.w=x2-x1+1; l.h=1;
62
+
63
+ SDL_FillRect(Surface, &l, Color);
64
+ }
65
+
66
+ //==================================================================================
67
+ // Draw horizontal line
68
+ //==================================================================================
69
+ void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
70
+ {
71
+ if(x1>x2){Sint16 tmp=x1; x1=x2; x2=tmp;}
72
+
73
+ //Do the clipping
74
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
75
+ SDL_VERSIONNUM(1, 1, 5)
76
+ if(y<Surface->clip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2<Surface->clip_minx)
77
+ return;
78
+ if(x1<Surface->clip_minx)
79
+ x1=Surface->clip_minx;
80
+ if(x2>Surface->clip_maxx)
81
+ x2=Surface->clip_maxx;
82
+ #endif
83
+
84
+ SDL_Rect l;
85
+ l.x=x1; l.y=y; l.w=x2-x1+1; l.h=1;
86
+
87
+ SDL_FillRect(Surface, &l, Color);
88
+
89
+ sge_UpdateRect(Surface, x1, y, x2-x1+1, 1);
90
+ }
91
+
92
+ //==================================================================================
93
+ // Draw horizontal line (RGB)
94
+ //==================================================================================
95
+ void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
96
+ {
97
+ sge_HLine(Surface,x1,x2,y, SDL_MapRGB(Surface->format, R, G, B));
98
+ }
99
+
100
+
101
+ //==================================================================================
102
+ // Internal draw horizontal line (alpha)
103
+ //==================================================================================
104
+ void _HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha)
105
+ {
106
+ Uint8 update = _sge_update;
107
+ Uint8 lock = _sge_lock;
108
+ _sge_update = 0;
109
+ _sge_lock = 0;
110
+ sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha);
111
+ _sge_update = update;
112
+ _sge_lock = lock;
113
+ }
114
+
115
+ //==================================================================================
116
+ // Draw horizontal line (alpha)
117
+ //==================================================================================
118
+ void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha)
119
+ {
120
+ sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha);
121
+ }
122
+
123
+ //==================================================================================
124
+ // Draw horizontal line (alpha RGB)
125
+ //==================================================================================
126
+ void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
127
+ {
128
+ sge_HLineAlpha(Surface,x1,x2,y, SDL_MapRGB(Surface->format, R, G, B), alpha);
129
+ }
130
+
131
+
132
+ //==================================================================================
133
+ // Internal draw vertical line
134
+ //==================================================================================
135
+ void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
136
+ {
137
+ if(y1>y2){Sint16 tmp=y1; y1=y2; y2=tmp;}
138
+
139
+ //Do the clipping
140
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
141
+ SDL_VERSIONNUM(1, 1, 5)
142
+ if(x<Surface->clip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2<Surface->clip_miny)
143
+ return;
144
+ if(y1<Surface->clip_miny)
145
+ y1=Surface->clip_miny;
146
+ if(y2>Surface->clip_maxy)
147
+ y2=Surface->clip_maxy;
148
+ #endif
149
+
150
+ SDL_Rect l;
151
+ l.x=x; l.y=y1; l.w=1; l.h=y2-y1+1;
152
+
153
+ SDL_FillRect(Surface, &l, Color);
154
+ }
155
+
156
+ //==================================================================================
157
+ // Draw vertical line
158
+ //==================================================================================
159
+ void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
160
+ {
161
+ if(y1>y2){Sint16 tmp=y1; y1=y2; y2=tmp;}
162
+
163
+ //Do the clipping
164
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
165
+ SDL_VERSIONNUM(1, 1, 5)
166
+ if(x<Surface->clip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2<Surface->clip_miny)
167
+ return;
168
+ if(y1<Surface->clip_miny)
169
+ y1=Surface->clip_miny;
170
+ if(y2>Surface->clip_maxy)
171
+ y2=Surface->clip_maxy;
172
+ #endif
173
+
174
+ SDL_Rect l;
175
+ l.x=x; l.y=y1; l.w=1; l.h=y2-y1+1;
176
+
177
+ SDL_FillRect(Surface, &l, Color);
178
+
179
+ sge_UpdateRect(Surface, x, y1, 1, y2-y1+1);
180
+ }
181
+
182
+ //==================================================================================
183
+ // Draw vertical line (RGB)
184
+ //==================================================================================
185
+ void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
186
+ {
187
+ sge_VLine(Surface,x,y1,y2, SDL_MapRGB(Surface->format, R, G, B));
188
+ }
189
+
190
+
191
+ //==================================================================================
192
+ // Internal draw vertical line (alpha - no update)
193
+ //==================================================================================
194
+ void _VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha)
195
+ {
196
+ Uint8 update = _sge_update;
197
+ Uint8 lock = _sge_lock;
198
+ _sge_update = 0;
199
+ _sge_lock = 0;
200
+ sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha);
201
+ _sge_update = update;
202
+ _sge_lock = lock;
203
+ }
204
+
205
+ //==================================================================================
206
+ // Draw vertical line (alpha)
207
+ //==================================================================================
208
+ void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha)
209
+ {
210
+ sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha);
211
+ }
212
+
213
+ //==================================================================================
214
+ // Draw vertical line (alpha RGB)
215
+ //==================================================================================
216
+ void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
217
+ {
218
+ sge_VLineAlpha(Surface,x,y1,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
219
+ }
220
+
221
+
222
+
223
+ //==================================================================================
224
+ // Performs Callback at each line point. (From PowerPak)
225
+ //==================================================================================
226
+ void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
227
+ {
228
+ Sint16 dx, dy, sdx, sdy, x, y, px, py;
229
+
230
+ dx = x2 - x1;
231
+ dy = y2 - y1;
232
+
233
+ sdx = (dx < 0) ? -1 : 1;
234
+ sdy = (dy < 0) ? -1 : 1;
235
+
236
+ dx = sdx * dx + 1;
237
+ dy = sdy * dy + 1;
238
+
239
+ x = y = 0;
240
+
241
+ px = x1;
242
+ py = y1;
243
+
244
+ if (dx >= dy){
245
+ for (x = 0; x < dx; x++){
246
+ Callback(Surface, px, py, Color);
247
+
248
+ y += dy;
249
+ if (y >= dx){
250
+ y -= dx;
251
+ py += sdy;
252
+ }
253
+ px += sdx;
254
+ }
255
+ }
256
+ else{
257
+ for (y = 0; y < dy; y++){
258
+ Callback(Surface, px, py, Color);
259
+
260
+ x += dx;
261
+ if (x >= dy){
262
+ x -= dy;
263
+ px += sdx;
264
+ }
265
+ py += sdy;
266
+ }
267
+ }
268
+ }
269
+
270
+
271
+ //==================================================================================
272
+ // Performs Callback at each line point. (RGB)
273
+ //==================================================================================
274
+ void sge_DoLine(SDL_Surface *Surface, Sint16 X1, Sint16 Y1, Sint16 X2, Sint16 Y2, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
275
+ {
276
+ sge_DoLine(Surface,X1,Y1,X2,Y2, SDL_MapRGB(Surface->format, R, G, B),Callback);
277
+ }
278
+
279
+
280
+ //==================================================================================
281
+ // Line clipping
282
+ // Standard Cohen-Sutherland algorithm (from gfxPrimitives)
283
+ //==================================================================================
284
+ #define CLIP_LEFT_EDGE 0x1
285
+ #define CLIP_RIGHT_EDGE 0x2
286
+ #define CLIP_BOTTOM_EDGE 0x4
287
+ #define CLIP_TOP_EDGE 0x8
288
+ #define CLIP_INSIDE(a) (!a)
289
+ #define CLIP_REJECT(a,b) (a&b)
290
+ #define CLIP_ACCEPT(a,b) (!(a|b))
291
+
292
+ int clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
293
+ {
294
+ int code = 0;
295
+
296
+ if (x < left)
297
+ code |= CLIP_LEFT_EDGE;
298
+ else if (x > right)
299
+ code |= CLIP_RIGHT_EDGE;
300
+
301
+ if (y < top)
302
+ code |= CLIP_TOP_EDGE;
303
+ else if (y > bottom)
304
+ code |= CLIP_BOTTOM_EDGE;
305
+
306
+ return code;
307
+ }
308
+
309
+ int clipLine(SDL_Surface *dst, Sint16 *x1, Sint16 *y1, Sint16 *x2, Sint16 *y2)
310
+ {
311
+ int code1, code2;
312
+ bool draw = false;
313
+
314
+ Sint16 tmp;
315
+ float m;
316
+
317
+ /* Get clipping boundary */
318
+ Sint16 left, right, top, bottom;
319
+ left = sge_clip_xmin(dst);
320
+ right = sge_clip_xmax(dst);
321
+ top = sge_clip_ymin(dst);
322
+ bottom = sge_clip_ymax(dst);
323
+
324
+ while (true){
325
+ code1 = clipEncode(*x1, *y1, left, top, right, bottom);
326
+ code2 = clipEncode(*x2, *y2, left, top, right, bottom);
327
+
328
+ if(CLIP_ACCEPT(code1, code2)){
329
+ draw = true;
330
+ break;
331
+ }else if(CLIP_REJECT(code1, code2))
332
+ break;
333
+ else{
334
+ if(CLIP_INSIDE(code1)){
335
+ tmp = *x2;
336
+ *x2 = *x1;
337
+ *x1 = tmp;
338
+ tmp = *y2;
339
+ *y2 = *y1;
340
+ *y1 = tmp;
341
+ tmp = code2;
342
+ code2 = code1;
343
+ code1 = tmp;
344
+ }
345
+ if(*x2 != *x1)
346
+ m = (*y2 - *y1) / float(*x2 - *x1);
347
+ else
348
+ m = 1.0;
349
+
350
+
351
+ if(code1 & CLIP_LEFT_EDGE){
352
+ *y1 += Sint16( (left - *x1) * m );
353
+ *x1 = left;
354
+ }else if(code1 & CLIP_RIGHT_EDGE){
355
+ *y1 += Sint16( (right - *x1) * m );
356
+ *x1 = right;
357
+ }else if(code1 & CLIP_BOTTOM_EDGE){
358
+ if (*x2 != *x1) {
359
+ *x1 += Sint16( (bottom - *y1) / m );
360
+ }
361
+ *y1 = bottom;
362
+ }else if(code1 & CLIP_TOP_EDGE){
363
+ if (*x2 != *x1) {
364
+ *x1 += Sint16( (top - *y1) / m );
365
+ }
366
+ *y1 = top;
367
+ }
368
+ }
369
+ }
370
+
371
+ return draw;
372
+ }
373
+
374
+
375
+ //==================================================================================
376
+ // Draws a line
377
+ //==================================================================================
378
+ void _Line(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
379
+ {
380
+ if( !clipLine(surface, &x1, &y1, &x2, &y2) )
381
+ return;
382
+
383
+ Sint16 dx, dy, sdx, sdy, x, y;
384
+
385
+ dx = x2 - x1;
386
+ dy = y2 - y1;
387
+
388
+ sdx = (dx < 0) ? -1 : 1;
389
+ sdy = (dy < 0) ? -1 : 1;
390
+
391
+ dx = sdx * dx + 1;
392
+ dy = sdy * dy + 1;
393
+
394
+ x = y = 0;
395
+
396
+ Sint16 pixx = surface->format->BytesPerPixel;
397
+ Sint16 pixy = surface->pitch;
398
+ Uint8 *pixel = (Uint8*)surface->pixels + y1*pixy + x1*pixx;
399
+
400
+ pixx *= sdx;
401
+ pixy *= sdy;
402
+
403
+ if (dx < dy) {
404
+ Sint32 tmp = dx; dx = dy; dy = Sint16(tmp);
405
+ tmp = pixx; pixx = pixy; pixy = tmp;
406
+ }
407
+
408
+ switch(surface->format->BytesPerPixel) {
409
+ case 1: {
410
+ for(x=0; x < dx; x++) {
411
+ *pixel = color;
412
+
413
+ y += dy;
414
+ if (y >= dx) {
415
+ y -= dx;
416
+ pixel += pixy;
417
+ }
418
+ pixel += pixx;
419
+ }
420
+ }
421
+ break;
422
+
423
+ case 2: {
424
+ for(x=0; x < dx; x++) {
425
+ *(Uint16*)pixel = color;
426
+
427
+ y += dy;
428
+ if (y >= dx) {
429
+ y -= dx;
430
+ pixel += pixy;
431
+ }
432
+ pixel += pixx;
433
+ }
434
+ }
435
+ break;
436
+
437
+ case 3: {
438
+ Uint8 rshift8 = surface->format->Rshift/8;
439
+ Uint8 gshift8 = surface->format->Gshift/8;
440
+ Uint8 bshift8 = surface->format->Bshift/8;
441
+ Uint8 ashift8 = surface->format->Ashift/8;
442
+
443
+ Uint8 R = (color>>surface->format->Rshift)&0xff;
444
+ Uint8 G = (color>>surface->format->Gshift)&0xff;
445
+ Uint8 B = (color>>surface->format->Bshift)&0xff;
446
+ Uint8 A = (color>>surface->format->Ashift)&0xff;
447
+
448
+ for(x=0; x < dx; x++) {
449
+ *(pixel+rshift8) = R;
450
+ *(pixel+gshift8) = G;
451
+ *(pixel+bshift8) = B;
452
+ *(pixel+ashift8) = A;
453
+
454
+ y += dy;
455
+ if (y >= dx) {
456
+ y -= dx;
457
+ pixel += pixy;
458
+ }
459
+ pixel += pixx;
460
+ }
461
+ }
462
+ break;
463
+
464
+ case 4: {
465
+ for(x=0; x < dx; x++) {
466
+ *(Uint32*)pixel = color;
467
+
468
+ y += dy;
469
+ if (y >= dx) {
470
+ y -= dx;
471
+ pixel += pixy;
472
+ }
473
+ pixel += pixx;
474
+ }
475
+ }
476
+ break;
477
+ }
478
+ }
479
+
480
+ void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color)
481
+ {
482
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
483
+ if (SDL_LockSurface(Surface) < 0)
484
+ return;
485
+ }
486
+
487
+ /* Draw the line */
488
+ _Line(Surface, x1,y1, x2,y2, Color);
489
+
490
+ /* unlock the display */
491
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
492
+ SDL_UnlockSurface(Surface);
493
+ }
494
+
495
+ sge_UpdateRect(Surface, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
496
+ }
497
+
498
+
499
+ //==================================================================================
500
+ // Draws a line (RGB)
501
+ //==================================================================================
502
+ void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
503
+ {
504
+ sge_Line(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
505
+ }
506
+
507
+
508
+ //==================================================================================
509
+ // A quick hack to get alpha working with callbacks
510
+ //==================================================================================
511
+ Uint8 _sge_alpha_hack = 0;
512
+ void callback_alpha_hack(SDL_Surface *surf, Sint16 x, Sint16 y, Uint32 color)
513
+ {
514
+ _PutPixelAlpha(surf,x,y,color,_sge_alpha_hack);
515
+ }
516
+
517
+ //==================================================================================
518
+ // Draws a line (alpha)
519
+ //==================================================================================
520
+ void _LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha)
521
+ {
522
+ _sge_alpha_hack = alpha;
523
+
524
+ /* Draw the line */
525
+ sge_DoLine(Surface, x1, y1, x2, y2, Color, callback_alpha_hack);
526
+ }
527
+
528
+ void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha)
529
+ {
530
+ if (SDL_MUSTLOCK(Surface) && _sge_lock)
531
+ if (SDL_LockSurface(Surface) < 0)
532
+ return;
533
+
534
+ _LineAlpha(Surface, x1, y1, x2, y2, Color, alpha);
535
+
536
+ /* unlock the display */
537
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
538
+ SDL_UnlockSurface(Surface);
539
+ }
540
+
541
+ sge_UpdateRect(Surface, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
542
+ }
543
+
544
+ //==================================================================================
545
+ // Draws a line (alpha - RGB)
546
+ //==================================================================================
547
+ void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
548
+ {
549
+ sge_LineAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
550
+ }
551
+
552
+
553
+ //==================================================================================
554
+ // Anti-aliased line
555
+ // From SDL_gfxPrimitives written by A. Schiffler (aschiffler@home.com)
556
+ //==================================================================================
557
+ #define AAbits 8
558
+ #define AAlevels 256 /* 2^AAbits */
559
+ void _AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
560
+ {
561
+ Uint32 erracc=0, erradj;
562
+ Uint32 erracctmp, wgt;
563
+ Sint16 tmp, y0p1, x0pxdir;
564
+ Uint8 a;
565
+
566
+ /* Keep on working with 32bit numbers */
567
+ Sint32 xx0=x1;
568
+ Sint32 yy0=y1;
569
+ Sint32 xx1=x2;
570
+ Sint32 yy1=y2;
571
+
572
+ /* Reorder points if required */
573
+ if (yy0 > yy1) {
574
+ SWAP(yy0, yy1, tmp);
575
+ SWAP(xx0, xx1, tmp);
576
+ }
577
+
578
+ /* Calculate distance */
579
+ Sint16 dx = xx1 - xx0;
580
+ Sint16 dy = yy1 - yy0;
581
+
582
+ /* Adjust for negative dx and set xdir */
583
+ Sint16 xdir = 1;
584
+ if (dx < 0) {
585
+ xdir=-1;
586
+ dx=(-dx);
587
+ }
588
+
589
+ /* Check for special cases */
590
+ if (dx==0 || dy==0 || dx==dy) {
591
+ if(alpha==SDL_ALPHA_OPAQUE)
592
+ _Line(dst,x1,y1,x2,y2,color);
593
+ else
594
+ _LineAlpha(dst,x1,y1,x2,y2,color,alpha);
595
+ return;
596
+ }
597
+
598
+ float alpha_pp = float(alpha)/255; /* Used to calculate alpha level if alpha != 255 */
599
+
600
+ Uint32 intshift = 32 - AAbits; /* # of bits by which to shift erracc to get intensity level */
601
+
602
+ /* Draw the initial pixel in the foreground color */
603
+ if(alpha==SDL_ALPHA_OPAQUE)
604
+ _PutPixel(dst,x1,y1, color);
605
+ else
606
+ _PutPixelAlpha(dst,x1,y1, color, alpha);
607
+
608
+ /* x-major or y-major? */
609
+ if (dy > dx) {
610
+
611
+ /* y-major. Calculate 16-bit fixed point fractional part of a pixel that
612
+ X advances every time Y advances 1 pixel, truncating the result so that
613
+ we won't overrun the endpoint along the X axis */
614
+ erradj = ((dx << 16) / dy)<<16;
615
+
616
+ /* draw all pixels other than the first and last */
617
+ x0pxdir=xx0+xdir;
618
+ while (--dy) {
619
+ erracctmp = erracc;
620
+ erracc += erradj;
621
+ if (erracc <= erracctmp) {
622
+ /* rollover in error accumulator, x coord advances */
623
+ xx0=x0pxdir;
624
+ x0pxdir += xdir;
625
+ }
626
+ yy0++; /* y-major so always advance Y */
627
+
628
+ /* the AAbits most significant bits of erracc give us the intensity
629
+ weighting for this pixel, and the complement of the weighting for
630
+ the paired pixel. */
631
+ wgt = (erracc >> intshift) & 255;
632
+
633
+ a = Uint8(255-wgt);
634
+ if(alpha != SDL_ALPHA_OPAQUE)
635
+ a = Uint8(a*alpha_pp);
636
+
637
+ _PutPixelAlpha(dst,xx0,yy0,color,a);
638
+
639
+ a = Uint8(wgt);
640
+ if(alpha != SDL_ALPHA_OPAQUE)
641
+ a = Uint8(a*alpha_pp);
642
+
643
+ _PutPixelAlpha(dst,x0pxdir,yy0,color,a);
644
+ }
645
+ } else {
646
+
647
+ /* x-major line. Calculate 16-bit fixed-point fractional part of a pixel
648
+ that Y advances each time X advances 1 pixel, truncating the result so
649
+ that we won't overrun the endpoint along the X axis. */
650
+ erradj = ((dy << 16) / dx)<<16;
651
+
652
+ /* draw all pixels other than the first and last */
653
+ y0p1=yy0+1;
654
+ while (--dx) {
655
+
656
+ erracctmp = erracc;
657
+ erracc += erradj;
658
+ if (erracc <= erracctmp) {
659
+ /* Accumulator turned over, advance y */
660
+ yy0=y0p1;
661
+ y0p1++;
662
+ }
663
+ xx0 += xdir; /* x-major so always advance X */
664
+
665
+ /* the AAbits most significant bits of erracc give us the intensity
666
+ weighting for this pixel, and the complement of the weighting for
667
+ the paired pixel. */
668
+ wgt = (erracc >> intshift) & 255;
669
+
670
+ a = Uint8(255-wgt);
671
+ if(alpha != SDL_ALPHA_OPAQUE)
672
+ a = Uint8(a*alpha_pp);
673
+
674
+ _PutPixelAlpha(dst,xx0,yy0,color,a);
675
+
676
+ a = Uint8(wgt);
677
+ if(alpha != SDL_ALPHA_OPAQUE)
678
+ a = Uint8(a*alpha_pp);
679
+
680
+ _PutPixelAlpha(dst,xx0,y0p1,color,a);
681
+ }
682
+ }
683
+
684
+ /* Draw final pixel, always exactly intersected by the line and doesn't
685
+ need to be weighted. */
686
+ if(alpha==SDL_ALPHA_OPAQUE)
687
+ _PutPixel(dst,x2,y2, color);
688
+ else
689
+ _PutPixelAlpha(dst,x2,y2, color, alpha);
690
+
691
+ }
692
+
693
+ void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
694
+ {
695
+ /* Lock surface */
696
+ if ( SDL_MUSTLOCK(dst) && _sge_lock )
697
+ if ( SDL_LockSurface(dst) < 0 )
698
+ return;
699
+
700
+ _AALineAlpha(dst,x1,y1,x2,y2,color,alpha);
701
+
702
+ /* unlock the display */
703
+ if (SDL_MUSTLOCK(dst) && _sge_lock) {
704
+ SDL_UnlockSurface(dst);
705
+ }
706
+
707
+ sge_UpdateRect(dst, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
708
+ }
709
+
710
+ void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha)
711
+ {
712
+ sge_AALineAlpha(dst,x1,y1,x2,y2,SDL_MapRGB(dst->format, r, g, b),alpha);
713
+ }
714
+
715
+ void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
716
+ {
717
+ sge_AALineAlpha(dst, x1,y1, x2,y2, color, SDL_ALPHA_OPAQUE);
718
+ }
719
+
720
+ void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b)
721
+ {
722
+ sge_AALineAlpha(dst,x1,y1,x2,y2,SDL_MapRGB(dst->format, r, g, b),SDL_ALPHA_OPAQUE);
723
+ }
724
+
725
+
726
+
727
+ //==================================================================================
728
+ // Draws a multicolored line
729
+ //==================================================================================
730
+ void sge_DomcLine(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
731
+ {
732
+ Sint16 dx, dy, sdx, sdy, x, y, px, py;
733
+
734
+ dx = x2 - x1;
735
+ dy = y2 - y1;
736
+
737
+ sdx = (dx < 0) ? -1 : 1;
738
+ sdy = (dy < 0) ? -1 : 1;
739
+
740
+ dx = sdx * dx + 1;
741
+ dy = sdy * dy + 1;
742
+
743
+ x = y = 0;
744
+
745
+ px = x1;
746
+ py = y1;
747
+
748
+ /* We use fixedpoint math for the color fading */
749
+ Sint32 R = r1<<16;
750
+ Sint32 G = g1<<16;
751
+ Sint32 B = b1<<16;
752
+ Sint32 rstep;
753
+ Sint32 gstep;
754
+ Sint32 bstep;
755
+
756
+ if (dx >= dy){
757
+ rstep = Sint32((r2-r1)<<16) / Sint32(dx);
758
+ gstep = Sint32((g2-g1)<<16) / Sint32(dx);
759
+ bstep = Sint32((b2-b1)<<16) / Sint32(dx);
760
+
761
+ for (x = 0; x < dx; x++){
762
+ Callback(surface, px, py, SDL_MapRGB(surface->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)) );
763
+
764
+ y += dy;
765
+ if (y >= dx){
766
+ y -= dx;
767
+ py += sdy;
768
+ }
769
+ px += sdx;
770
+
771
+ R += rstep;
772
+ G += gstep;
773
+ B += bstep;
774
+ }
775
+ }
776
+ else{
777
+ rstep = Sint32((r2-r1)<<16) / Sint32(dy);
778
+ gstep = Sint32((g2-g1)<<16) / Sint32(dy);
779
+ bstep = Sint32((b2-b1)<<16) / Sint32(dy);
780
+
781
+ for (y = 0; y < dy; y++){
782
+ Callback(surface, px, py, SDL_MapRGB(surface->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)) );
783
+
784
+ x += dx;
785
+ if (x >= dy){
786
+ x -= dy;
787
+ px += sdx;
788
+ }
789
+ py += sdy;
790
+
791
+ R += rstep;
792
+ G += gstep;
793
+ B += bstep;
794
+ }
795
+ }
796
+ }
797
+
798
+ void sge_mcLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2)
799
+ {
800
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
801
+ if (SDL_LockSurface(Surface) < 0)
802
+ return;
803
+ }
804
+
805
+ /* Draw the line */
806
+ sge_DomcLine(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, _PutPixel);
807
+
808
+ /* unlock the display */
809
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
810
+ SDL_UnlockSurface(Surface);
811
+ }
812
+
813
+ sge_UpdateRect(Surface, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
814
+ }
815
+
816
+ void sge_mcLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2, Uint8 alpha)
817
+ {
818
+ if (SDL_MUSTLOCK(Surface) && _sge_lock)
819
+ if (SDL_LockSurface(Surface) < 0)
820
+ return;
821
+
822
+ _sge_alpha_hack = alpha;
823
+
824
+ /* Draw the line */
825
+ sge_DomcLine(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, callback_alpha_hack);
826
+
827
+ /* unlock the display */
828
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
829
+ SDL_UnlockSurface(Surface);
830
+ }
831
+
832
+ sge_UpdateRect(Surface, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
833
+ }
834
+
835
+
836
+ //==================================================================================
837
+ // Draws a anti-aliased multicolored line
838
+ //==================================================================================
839
+ 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)
840
+ {
841
+ Uint32 erracc=0, erradj;
842
+ Uint32 erracctmp, wgt;
843
+ Sint16 tmp, y0p1, x0pxdir;
844
+ Uint8 a;
845
+
846
+ /* Keep on working with 32bit numbers */
847
+ Sint32 xx0=x1;
848
+ Sint32 yy0=y1;
849
+ Sint32 xx1=x2;
850
+ Sint32 yy1=y2;
851
+
852
+ /* Reorder points if required */
853
+ if (yy0 > yy1) {
854
+ SWAP(yy0, yy1, tmp);
855
+ SWAP(xx0, xx1, tmp);
856
+
857
+ SWAP(r1, r2, a);
858
+ SWAP(g1, g2, a);
859
+ SWAP(b1, b2, a);
860
+ }
861
+
862
+ /* Calculate distance */
863
+ Sint16 dx = xx1 - xx0;
864
+ Sint16 dy = yy1 - yy0;
865
+
866
+ /* Adjust for negative dx and set xdir */
867
+ Sint16 xdir=1;
868
+ if (dx < 0) {
869
+ xdir=-1;
870
+ dx=(-dx);
871
+ }
872
+
873
+ /* Check for special cases */
874
+ if (dx==0 || dy==0 || dx==dy) {
875
+ sge_mcLineAlpha(dst, x1, y1, x2, y2, r1, g1, b1, r2, g2, b2, alpha);
876
+ return;
877
+ }
878
+
879
+ /* We use fixedpoint math for the color fading */
880
+ Sint32 R = r1<<16;
881
+ Sint32 G = g1<<16;
882
+ Sint32 B = b1<<16;
883
+ Sint32 rstep;
884
+ Sint32 gstep;
885
+ Sint32 bstep;
886
+
887
+ float alpha_pp = float(alpha)/255; /* Used to calculate alpha level if alpha != 255 */
888
+ Uint32 intshift = 32 - AAbits; /* # of bits by which to shift erracc to get intensity level */
889
+
890
+ if(alpha==255)
891
+ _PutPixel(dst,x1,y1, SDL_MapRGB(dst->format, r1, g1, b1) ); /* Draw the initial pixel in the foreground color */
892
+ else
893
+ _PutPixelAlpha(dst,x1,y1, SDL_MapRGB(dst->format, r1, g1, b1), alpha);
894
+
895
+ /* x-major or y-major? */
896
+ if (dy > dx) {
897
+
898
+ /* y-major. Calculate 16-bit fixed point fractional part of a pixel that
899
+ X advances every time Y advances 1 pixel, truncating the result so that
900
+ we won't overrun the endpoint along the X axis */
901
+ erradj = ((dx << 16) / dy)<<16;
902
+
903
+ rstep = Sint32((r2-r1)<<16) / Sint32(dy);
904
+ gstep = Sint32((g2-g1)<<16) / Sint32(dy);
905
+ bstep = Sint32((b2-b1)<<16) / Sint32(dy);
906
+
907
+ /* draw all pixels other than the first and last */
908
+ x0pxdir=xx0+xdir;
909
+ while (--dy) {
910
+ R += rstep;
911
+ G += gstep;
912
+ B += bstep;
913
+
914
+ erracctmp = erracc;
915
+ erracc += erradj;
916
+ if (erracc <= erracctmp) {
917
+ /* rollover in error accumulator, x coord advances */
918
+ xx0=x0pxdir;
919
+ x0pxdir += xdir;
920
+ }
921
+ yy0++; /* y-major so always advance Y */
922
+
923
+ /* the AAbits most significant bits of erracc give us the intensity
924
+ weighting for this pixel, and the complement of the weighting for
925
+ the paired pixel. */
926
+ wgt = (erracc >> intshift) & 255;
927
+
928
+ a = Uint8(255-wgt);
929
+ if(alpha != 255)
930
+ a = Uint8(a*alpha_pp);
931
+
932
+ _PutPixelAlpha(dst,xx0,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
933
+
934
+ a = Uint8(wgt);
935
+ if(alpha != 255)
936
+ a = Uint8(a*alpha_pp);
937
+
938
+ _PutPixelAlpha(dst,x0pxdir,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
939
+ }
940
+ } else {
941
+
942
+ /* x-major line. Calculate 16-bit fixed-point fractional part of a pixel
943
+ that Y advances each time X advances 1 pixel, truncating the result so
944
+ that we won't overrun the endpoint along the X axis. */
945
+ erradj = ((dy << 16) / dx)<<16;
946
+
947
+ rstep = Sint32((r2-r1)<<16) / Sint32(dx);
948
+ gstep = Sint32((g2-g1)<<16) / Sint32(dx);
949
+ bstep = Sint32((b2-b1)<<16) / Sint32(dx);
950
+
951
+ /* draw all pixels other than the first and last */
952
+ y0p1=yy0+1;
953
+ while (--dx) {
954
+ R += rstep;
955
+ G += gstep;
956
+ B += bstep;
957
+
958
+ erracctmp = erracc;
959
+ erracc += erradj;
960
+ if (erracc <= erracctmp) {
961
+ /* Accumulator turned over, advance y */
962
+ yy0=y0p1;
963
+ y0p1++;
964
+ }
965
+ xx0 += xdir; /* x-major so always advance X */
966
+
967
+ /* the AAbits most significant bits of erracc give us the intensity
968
+ weighting for this pixel, and the complement of the weighting for
969
+ the paired pixel. */
970
+ wgt = (erracc >> intshift) & 255;
971
+
972
+ a = Uint8(255-wgt);
973
+ if(alpha != 255)
974
+ a = Uint8(a*alpha_pp);
975
+
976
+ _PutPixelAlpha(dst,xx0,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
977
+
978
+ a = Uint8(wgt);
979
+ if(alpha != 255)
980
+ a = Uint8(a*alpha_pp);
981
+
982
+ _PutPixelAlpha(dst,xx0,y0p1,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
983
+ }
984
+ }
985
+
986
+ /* Draw final pixel, always exactly intersected by the line and doesn't
987
+ need to be weighted. */
988
+ if(alpha==255)
989
+ _PutPixel(dst,x2,y2, SDL_MapRGB(dst->format,r2, g2, b2));
990
+ else
991
+ _PutPixelAlpha(dst,x2,y2, SDL_MapRGB(dst->format,r2, g2, b2), alpha);
992
+
993
+ }
994
+
995
+ void sge_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)
996
+ {
997
+ if ( SDL_MUSTLOCK(dst) && _sge_lock )
998
+ if ( SDL_LockSurface(dst) < 0 )
999
+ return;
1000
+
1001
+ _AAmcLineAlpha(dst, x1, y1, x2, y2, r1, g1, b1, r2, g2, b2, alpha);
1002
+
1003
+ if (SDL_MUSTLOCK(dst) && _sge_lock)
1004
+ SDL_UnlockSurface(dst);
1005
+
1006
+ sge_UpdateRect(dst, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
1007
+ }
1008
+
1009
+ void sge_AAmcLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2)
1010
+ {
1011
+ sge_AAmcLineAlpha(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, SDL_ALPHA_OPAQUE);
1012
+ }
1013
+
1014
+
1015
+
1016
+ /**********************************************************************************/
1017
+ /** Figure functions **/
1018
+ /**********************************************************************************/
1019
+
1020
+ //==================================================================================
1021
+ // Draws a rectangle
1022
+ //==================================================================================
1023
+ void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
1024
+ {
1025
+ _HLine(Surface,x1,x2,y1,color);
1026
+ _HLine(Surface,x1,x2,y2,color);
1027
+ _VLine(Surface,x1,y1,y2,color);
1028
+ _VLine(Surface,x2,y1,y2,color);
1029
+
1030
+ sge_UpdateRect(Surface, x1, y1, x2-x1, 1);
1031
+ sge_UpdateRect(Surface, x1, y2, x2-x1+1, 1); /* Hmm? */
1032
+ sge_UpdateRect(Surface, x1, y1, 1, y2-y1);
1033
+ sge_UpdateRect(Surface, x2, y1, 1, y2-y1);
1034
+ }
1035
+
1036
+ //==================================================================================
1037
+ // Draws a rectangle (RGB)
1038
+ //==================================================================================
1039
+ void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
1040
+ {
1041
+ sge_Rect(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
1042
+ }
1043
+
1044
+
1045
+ //==================================================================================
1046
+ // Draws a rectangle (alpha)
1047
+ //==================================================================================
1048
+ void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
1049
+ {
1050
+ if (SDL_MUSTLOCK(Surface) && _sge_lock)
1051
+ if (SDL_LockSurface(Surface) < 0)
1052
+ return;
1053
+
1054
+ _HLineAlpha(Surface,x1,x2,y1,color,alpha);
1055
+ _HLineAlpha(Surface,x1,x2,y2,color,alpha);
1056
+ _VLineAlpha(Surface,x1,y1,y2,color,alpha);
1057
+ _VLineAlpha(Surface,x2,y1,y2,color,alpha);
1058
+
1059
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
1060
+ SDL_UnlockSurface(Surface);
1061
+ }
1062
+
1063
+ sge_UpdateRect(Surface, x1, y1, x2-x1, 1);
1064
+ sge_UpdateRect(Surface, x1, y2, x2-x1+1, 1); /* Hmm? */
1065
+ sge_UpdateRect(Surface, x1, y1, 1, y2-y1);
1066
+ sge_UpdateRect(Surface, x2, y1, 1, y2-y1);
1067
+ }
1068
+
1069
+ //==================================================================================
1070
+ // Draws a rectangle (RGB)
1071
+ //==================================================================================
1072
+ void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
1073
+ {
1074
+ sge_RectAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
1075
+ }
1076
+
1077
+
1078
+ //==================================================================================
1079
+ // Draws a filled rectangle
1080
+ //==================================================================================
1081
+ void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
1082
+ {
1083
+ Sint16 tmp;
1084
+ if(x1>x2){
1085
+ tmp=x1; x1=x2; x2=tmp;
1086
+ }
1087
+ if(y1>y2){
1088
+ tmp=y1; y1=y2; y2=tmp;
1089
+ }
1090
+
1091
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
1092
+ SDL_VERSIONNUM(1, 1, 5)
1093
+ if(x2<Surface->clip_minx || x1>Surface->clip_maxx || y2<Surface->clip_miny || y1>Surface->clip_maxy)
1094
+ return;
1095
+ if (x1 < Surface->clip_minx)
1096
+ x1=Surface->clip_minx;
1097
+ if (x2 > Surface->clip_maxx)
1098
+ x2=Surface->clip_maxx;
1099
+ if (y1 < Surface->clip_miny)
1100
+ y1=Surface->clip_miny;
1101
+ if (y2 > Surface->clip_maxy)
1102
+ y2=Surface->clip_maxy;
1103
+ #endif
1104
+
1105
+ SDL_Rect area;
1106
+ area.x=x1; area.y=y1;
1107
+ area.w=x2-x1+1; area.h=y2-y1+1;
1108
+
1109
+ SDL_FillRect(Surface,&area,color);
1110
+
1111
+ sge_UpdateRect(Surface, x1, y1, x2-x1+1, y2-y1+1);
1112
+ }
1113
+
1114
+ //==================================================================================
1115
+ // Draws a filled rectangle (RGB)
1116
+ //==================================================================================
1117
+ void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
1118
+ {
1119
+ sge_FilledRect(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
1120
+ }
1121
+
1122
+
1123
+ //==================================================================================
1124
+ // Draws a filled rectangle (alpha)
1125
+ //==================================================================================
1126
+ void sge_FilledRectAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
1127
+ {
1128
+ /*if( alpha == 255 ){
1129
+ sge_FilledRect(surface,x1,y1,x2,y2,color);
1130
+ return;
1131
+ }*/
1132
+
1133
+ /* Fix coords */
1134
+ Sint16 tmp;
1135
+ if(x1>x2){
1136
+ tmp=x1; x1=x2; x2=tmp;
1137
+ }
1138
+ if(y1>y2){
1139
+ tmp=y1; y1=y2; y2=tmp;
1140
+ }
1141
+
1142
+ /* Clipping */
1143
+ if(x2<sge_clip_xmin(surface) || x1>sge_clip_xmax(surface) || y2<sge_clip_ymin(surface) || y1>sge_clip_ymax(surface))
1144
+ return;
1145
+ if (x1 < sge_clip_xmin(surface))
1146
+ x1 = sge_clip_xmin(surface);
1147
+ if (x2 > sge_clip_xmax(surface))
1148
+ x2 = sge_clip_xmax(surface);
1149
+ if (y1 < sge_clip_ymin(surface))
1150
+ y1 = sge_clip_ymin(surface);
1151
+ if (y2 > sge_clip_ymax(surface))
1152
+ y2 = sge_clip_ymax(surface);
1153
+
1154
+ Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
1155
+ Uint32 R,G,B,A=0;
1156
+ Sint16 x,y;
1157
+
1158
+ if (SDL_MUSTLOCK(surface) && _sge_lock)
1159
+ if (SDL_LockSurface(surface) < 0)
1160
+ return;
1161
+
1162
+ switch (surface->format->BytesPerPixel) {
1163
+ case 1: { /* Assuming 8-bpp */
1164
+ Uint8 *row, *pixel;
1165
+ Uint8 dR, dG, dB;
1166
+
1167
+ Uint8 sR = surface->format->palette->colors[color].r;
1168
+ Uint8 sG = surface->format->palette->colors[color].g;
1169
+ Uint8 sB = surface->format->palette->colors[color].b;
1170
+
1171
+ for(y = y1; y<=y2; y++){
1172
+ row = (Uint8 *)surface->pixels + y*surface->pitch;
1173
+ for(x = x1; x <= x2; x++){
1174
+ pixel = row + x;
1175
+
1176
+ dR = surface->format->palette->colors[*pixel].r;
1177
+ dG = surface->format->palette->colors[*pixel].g;
1178
+ dB = surface->format->palette->colors[*pixel].b;
1179
+
1180
+ dR = dR + ((sR-dR)*alpha >> 8);
1181
+ dG = dG + ((sG-dG)*alpha >> 8);
1182
+ dB = dB + ((sB-dB)*alpha >> 8);
1183
+
1184
+ *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
1185
+ }
1186
+ }
1187
+ }
1188
+ break;
1189
+
1190
+ case 2: { /* Probably 15-bpp or 16-bpp */
1191
+ Uint16 *row, *pixel;
1192
+ Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask);
1193
+
1194
+ for(y = y1; y<=y2; y++){
1195
+ row = (Uint16 *)surface->pixels + y*surface->pitch/2;
1196
+ for(x = x1; x <= x2; x++){
1197
+ pixel = row + x;
1198
+
1199
+ R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask;
1200
+ G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask;
1201
+ B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask;
1202
+ if( Amask )
1203
+ A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask;
1204
+
1205
+ *pixel= R | G | B | A;
1206
+ }
1207
+ }
1208
+ }
1209
+ break;
1210
+
1211
+ case 3: { /* Slow 24-bpp mode, usually not used */
1212
+ Uint8 *row,*pix;
1213
+ Uint8 dR, dG, dB, dA;
1214
+ Uint8 rshift8=surface->format->Rshift/8;
1215
+ Uint8 gshift8=surface->format->Gshift/8;
1216
+ Uint8 bshift8=surface->format->Bshift/8;
1217
+ Uint8 ashift8=surface->format->Ashift/8;
1218
+
1219
+ Uint8 sR = (color>>surface->format->Rshift)&0xff;
1220
+ Uint8 sG = (color>>surface->format->Gshift)&0xff;
1221
+ Uint8 sB = (color>>surface->format->Bshift)&0xff;
1222
+ Uint8 sA = (color>>surface->format->Ashift)&0xff;
1223
+
1224
+ for(y = y1; y<=y2; y++){
1225
+ row = (Uint8 *)surface->pixels + y * surface->pitch;
1226
+ for(x = x1; x <= x2; x++){
1227
+ pix = row + x*3;
1228
+
1229
+ dR = *((pix)+rshift8);
1230
+ dG = *((pix)+gshift8);
1231
+ dB = *((pix)+bshift8);
1232
+ dA = *((pix)+ashift8);
1233
+
1234
+ dR = dR + ((sR-dR)*alpha >> 8);
1235
+ dG = dG + ((sG-dG)*alpha >> 8);
1236
+ dB = dB + ((sB-dB)*alpha >> 8);
1237
+ dA = dA + ((sA-dA)*alpha >> 8);
1238
+
1239
+ *((pix)+rshift8) = dR;
1240
+ *((pix)+gshift8) = dG;
1241
+ *((pix)+bshift8) = dB;
1242
+ *((pix)+ashift8) = dA;
1243
+ }
1244
+ }
1245
+
1246
+ }
1247
+ break;
1248
+
1249
+ case 4: { /* Probably 32-bpp */
1250
+ Uint32 *row, *pixel;
1251
+ Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask);
1252
+
1253
+ for(y = y1; y<=y2; y++){
1254
+ row = (Uint32 *)surface->pixels + y*surface->pitch/4;
1255
+ for(x = x1; x <= x2; x++){
1256
+ pixel = row + x;
1257
+
1258
+ R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask;
1259
+ G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask;
1260
+ B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask;
1261
+ if( Amask )
1262
+ A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask;
1263
+
1264
+ *pixel= R | G | B | A;
1265
+ }
1266
+ }
1267
+ }
1268
+ break;
1269
+ }
1270
+
1271
+ if (SDL_MUSTLOCK(surface) && _sge_lock) {
1272
+ SDL_UnlockSurface(surface);
1273
+ }
1274
+
1275
+ sge_UpdateRect(surface, x1, y1, x2-x1+1, y2-y1+1);
1276
+ }
1277
+
1278
+ void sge_FilledRectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
1279
+ {
1280
+ sge_FilledRectAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
1281
+ }
1282
+
1283
+
1284
+ //==================================================================================
1285
+ // Performs Callback at each ellipse point.
1286
+ // (from Allegro)
1287
+ //==================================================================================
1288
+ void sge_DoEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color) )
1289
+ {
1290
+ int ix, iy;
1291
+ int h, i, j, k;
1292
+ int oh, oi, oj, ok;
1293
+
1294
+ if (rx < 1)
1295
+ rx = 1;
1296
+
1297
+ if (ry < 1)
1298
+ ry = 1;
1299
+
1300
+ h = i = j = k = 0xFFFF;
1301
+
1302
+ if (rx > ry) {
1303
+ ix = 0;
1304
+ iy = rx * 64;
1305
+
1306
+ do {
1307
+ oh = h;
1308
+ oi = i;
1309
+ oj = j;
1310
+ ok = k;
1311
+
1312
+ h = (ix + 32) >> 6;
1313
+ i = (iy + 32) >> 6;
1314
+ j = (h * ry) / rx;
1315
+ k = (i * ry) / rx;
1316
+
1317
+ if (((h != oh) || (k != ok)) && (h < oi)) {
1318
+ Callback(Surface, x+h, y+k, color);
1319
+ if (h)
1320
+ Callback(Surface, x-h, y+k, color);
1321
+ if (k) {
1322
+ Callback(Surface, x+h, y-k, color);
1323
+ if (h)
1324
+ Callback(Surface, x-h, y-k, color);
1325
+ }
1326
+ }
1327
+
1328
+ if (((i != oi) || (j != oj)) && (h < i)) {
1329
+ Callback(Surface, x+i, y+j, color);
1330
+ if (i)
1331
+ Callback(Surface, x-i, y+j, color);
1332
+ if (j) {
1333
+ Callback(Surface, x+i, y-j, color);
1334
+ if (i)
1335
+ Callback(Surface, x-i, y-j, color);
1336
+ }
1337
+ }
1338
+
1339
+ ix = ix + iy / rx;
1340
+ iy = iy - ix / rx;
1341
+
1342
+ } while (i > h);
1343
+ }
1344
+ else {
1345
+ ix = 0;
1346
+ iy = ry * 64;
1347
+
1348
+ do {
1349
+ oh = h;
1350
+ oi = i;
1351
+ oj = j;
1352
+ ok = k;
1353
+
1354
+ h = (ix + 32) >> 6;
1355
+ i = (iy + 32) >> 6;
1356
+ j = (h * rx) / ry;
1357
+ k = (i * rx) / ry;
1358
+
1359
+ if (((j != oj) || (i != oi)) && (h < i)) {
1360
+ Callback(Surface, x+j, y+i, color);
1361
+ if (j)
1362
+ Callback(Surface, x-j, y+i, color);
1363
+ if (i) {
1364
+ Callback(Surface, x+j, y-i, color);
1365
+ if (j)
1366
+ Callback(Surface, x-j, y-i, color);
1367
+ }
1368
+ }
1369
+
1370
+ if (((k != ok) || (h != oh)) && (h < oi)) {
1371
+ Callback(Surface, x+k, y+h, color);
1372
+ if (k)
1373
+ Callback(Surface, x-k, y+h, color);
1374
+ if (h) {
1375
+ Callback(Surface, x+k, y-h, color);
1376
+ if (k)
1377
+ Callback(Surface, x-k, y-h, color);
1378
+ }
1379
+ }
1380
+
1381
+ ix = ix + iy / ry;
1382
+ iy = iy - ix / ry;
1383
+
1384
+ } while(i > h);
1385
+ }
1386
+ }
1387
+
1388
+
1389
+ //==================================================================================
1390
+ // Performs Callback at each ellipse point. (RGB)
1391
+ //==================================================================================
1392
+ void sge_DoEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color) )
1393
+ {
1394
+ sge_DoEllipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),Callback);
1395
+ }
1396
+
1397
+
1398
+ //==================================================================================
1399
+ // Draws an ellipse
1400
+ //==================================================================================
1401
+ void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
1402
+ {
1403
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
1404
+ if (SDL_LockSurface(Surface) < 0)
1405
+ return;
1406
+ }
1407
+
1408
+ sge_DoEllipse(Surface, x, y, rx, ry, color, _PutPixel);
1409
+
1410
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
1411
+ SDL_UnlockSurface(Surface);
1412
+ }
1413
+
1414
+ sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
1415
+
1416
+ }
1417
+
1418
+
1419
+ //==================================================================================
1420
+ // Draws an ellipse (RGB)
1421
+ //==================================================================================
1422
+ void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
1423
+ {
1424
+ sge_Ellipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B));
1425
+ }
1426
+
1427
+
1428
+ //==================================================================================
1429
+ // Draws an ellipse (alpha)
1430
+ //==================================================================================
1431
+ void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
1432
+ {
1433
+ if (SDL_MUSTLOCK(Surface) && _sge_lock)
1434
+ if (SDL_LockSurface(Surface) < 0)
1435
+ return;
1436
+
1437
+ _sge_alpha_hack = alpha;
1438
+ sge_DoEllipse(Surface, x, y, rx, ry, color, callback_alpha_hack);
1439
+
1440
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
1441
+ SDL_UnlockSurface(Surface);
1442
+ }
1443
+
1444
+ sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
1445
+ }
1446
+
1447
+
1448
+ //==================================================================================
1449
+ // Draws an ellipse (alpha - RGB)
1450
+ //==================================================================================
1451
+ void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
1452
+ {
1453
+ sge_EllipseAlpha(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),alpha);
1454
+ }
1455
+
1456
+
1457
+ //==================================================================================
1458
+ // Draws a filled ellipse
1459
+ //==================================================================================
1460
+ void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
1461
+ {
1462
+ int ix, iy;
1463
+ int h, i, j, k;
1464
+ int oh, oi, oj, ok;
1465
+
1466
+ if (rx < 1)
1467
+ rx = 1;
1468
+
1469
+ if (ry < 1)
1470
+ ry = 1;
1471
+
1472
+ oh = oi = oj = ok = 0xFFFF;
1473
+
1474
+ if (rx > ry) {
1475
+ ix = 0;
1476
+ iy = rx * 64;
1477
+
1478
+ do {
1479
+ h = (ix + 32) >> 6;
1480
+ i = (iy + 32) >> 6;
1481
+ j = (h * ry) / rx;
1482
+ k = (i * ry) / rx;
1483
+
1484
+ if ((k!=ok) && (k!=oj)) {
1485
+ if (k){
1486
+ _HLine(Surface,x-h,x+h,y-k,color);
1487
+ _HLine(Surface,x-h,x+h,y+k,color);
1488
+ }else
1489
+ _HLine(Surface,x-h,x+h,y,color);
1490
+ ok=k;
1491
+ }
1492
+
1493
+ if ((j!=oj) && (j!=ok) && (k!=j)) {
1494
+ if (j){
1495
+ _HLine(Surface,x-i,x+i,y-j,color);
1496
+ _HLine(Surface,x-i,x+i,y+j,color);
1497
+ }else
1498
+ _HLine(Surface,x-i,x+i,y,color);
1499
+ oj=j;
1500
+ }
1501
+
1502
+ ix = ix + iy / rx;
1503
+ iy = iy - ix / rx;
1504
+
1505
+ } while (i > h);
1506
+ }
1507
+ else {
1508
+ ix = 0;
1509
+ iy = ry * 64;
1510
+
1511
+ do {
1512
+ h = (ix + 32) >> 6;
1513
+ i = (iy + 32) >> 6;
1514
+ j = (h * rx) / ry;
1515
+ k = (i * rx) / ry;
1516
+
1517
+ if ((i!=oi) && (i!=oh)) {
1518
+ if (i){
1519
+ _HLine(Surface,x-j,x+j,y-i,color);
1520
+ _HLine(Surface,x-j,x+j,y+i,color);
1521
+ }else
1522
+ _HLine(Surface,x-j,x+j,y,color);
1523
+ oi=i;
1524
+ }
1525
+
1526
+ if ((h!=oh) && (h!=oi) && (i!=h)) {
1527
+ if (h){
1528
+ _HLine(Surface,x-k,x+k,y-h,color);
1529
+ _HLine(Surface,x-k,x+k,y+h,color);
1530
+ }else
1531
+ _HLine(Surface,x-k,x+k,y,color);
1532
+ oh=h;
1533
+ }
1534
+
1535
+ ix = ix + iy / ry;
1536
+ iy = iy - ix / ry;
1537
+
1538
+ } while(i > h);
1539
+ }
1540
+
1541
+ sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
1542
+ }
1543
+
1544
+
1545
+ //==================================================================================
1546
+ // Draws a filled ellipse (RGB)
1547
+ //==================================================================================
1548
+ void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
1549
+ {
1550
+ sge_FilledEllipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B));
1551
+ }
1552
+
1553
+
1554
+
1555
+ //==================================================================================
1556
+ // Draws a filled ellipse (alpha)
1557
+ //==================================================================================
1558
+ void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
1559
+ {
1560
+ int ix, iy;
1561
+ int h, i, j, k;
1562
+ int oh, oi, oj, ok;
1563
+
1564
+ if (SDL_MUSTLOCK(Surface) && _sge_lock)
1565
+ if (SDL_LockSurface(Surface) < 0)
1566
+ return;
1567
+
1568
+ if (rx < 1)
1569
+ rx = 1;
1570
+
1571
+ if (ry < 1)
1572
+ ry = 1;
1573
+
1574
+ oh = oi = oj = ok = 0xFFFF;
1575
+
1576
+ if (rx > ry) {
1577
+ ix = 0;
1578
+ iy = rx * 64;
1579
+
1580
+ do {
1581
+ h = (ix + 32) >> 6;
1582
+ i = (iy + 32) >> 6;
1583
+ j = (h * ry) / rx;
1584
+ k = (i * ry) / rx;
1585
+
1586
+ if ((k!=ok) && (k!=oj)) {
1587
+ if (k){
1588
+ _HLineAlpha(Surface,x-h,x+h,y-k,color,alpha);
1589
+ _HLineAlpha(Surface,x-h,x+h,y+k,color,alpha);
1590
+ }else
1591
+ _HLineAlpha(Surface,x-h,x+h,y,color,alpha);
1592
+ ok=k;
1593
+ }
1594
+
1595
+ if ((j!=oj) && (j!=ok) && (k!=j)) {
1596
+ if (j){
1597
+ _HLineAlpha(Surface,x-i,x+i,y-j,color,alpha);
1598
+ _HLineAlpha(Surface,x-i,x+i,y+j,color,alpha);
1599
+ }else
1600
+ _HLineAlpha(Surface,x-i,x+i,y,color,alpha);
1601
+ oj=j;
1602
+ }
1603
+
1604
+ ix = ix + iy / rx;
1605
+ iy = iy - ix / rx;
1606
+
1607
+ } while (i > h);
1608
+ }
1609
+ else {
1610
+ ix = 0;
1611
+ iy = ry * 64;
1612
+
1613
+ do {
1614
+ h = (ix + 32) >> 6;
1615
+ i = (iy + 32) >> 6;
1616
+ j = (h * rx) / ry;
1617
+ k = (i * rx) / ry;
1618
+
1619
+ if ((i!=oi) && (i!=oh)) {
1620
+ if (i){
1621
+ _HLineAlpha(Surface,x-j,x+j,y-i,color,alpha);
1622
+ _HLineAlpha(Surface,x-j,x+j,y+i,color,alpha);
1623
+ }else
1624
+ _HLineAlpha(Surface,x-j,x+j,y,color,alpha);
1625
+ oi=i;
1626
+ }
1627
+
1628
+ if ((h!=oh) && (h!=oi) && (i!=h)) {
1629
+ if (h){
1630
+ _HLineAlpha(Surface,x-k,x+k,y-h,color,alpha);
1631
+ _HLineAlpha(Surface,x-k,x+k,y+h,color,alpha);
1632
+ }else
1633
+ _HLineAlpha(Surface,x-k,x+k,y,color,alpha);
1634
+ oh=h;
1635
+ }
1636
+
1637
+ ix = ix + iy / ry;
1638
+ iy = iy - ix / ry;
1639
+
1640
+ } while(i > h);
1641
+ }
1642
+
1643
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
1644
+ SDL_UnlockSurface(Surface);
1645
+ }
1646
+
1647
+ sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
1648
+ }
1649
+
1650
+
1651
+ //==================================================================================
1652
+ // Draws a filled ellipse (alpha - RGB)
1653
+ //==================================================================================
1654
+ void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
1655
+ {
1656
+ sge_FilledEllipseAlpha(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),alpha);
1657
+ }
1658
+
1659
+
1660
+ //==================================================================================
1661
+ // Draws an anti-aliased ellipse (alpha)
1662
+ // Some of this code is taken from "TwinLib" (http://www.twinlib.org) written by
1663
+ // Nicolas Roard (nicolas@roard.com)
1664
+ //==================================================================================
1665
+ void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
1666
+ {
1667
+ /* Sanity check */
1668
+ if (rx < 1)
1669
+ rx = 1;
1670
+ if (ry < 1)
1671
+ ry = 1;
1672
+
1673
+ int a2 = rx * rx;
1674
+ int b2 = ry * ry;
1675
+
1676
+ int ds = 2 * a2;
1677
+ int dt = 2 * b2;
1678
+
1679
+ int dxt = int (a2 / sqrt(a2 + b2));
1680
+
1681
+ int t = 0;
1682
+ int s = -2 * a2 * ry;
1683
+ int d = 0;
1684
+
1685
+ Sint16 x = xc;
1686
+ Sint16 y = yc - ry;
1687
+
1688
+ Sint16 xs, ys, dyt;
1689
+ float cp, is, ip, imax = 1.0;
1690
+
1691
+ Uint8 s_alpha, p_alpha;
1692
+ float alpha_pp = float(alpha)/255;
1693
+
1694
+ /* Lock surface */
1695
+ if ( SDL_MUSTLOCK(surface) && _sge_lock )
1696
+ if ( SDL_LockSurface(surface) < 0 )
1697
+ return;
1698
+
1699
+ /* "End points" */
1700
+ _PutPixelAlpha(surface, x, y, color, alpha);
1701
+ _PutPixelAlpha(surface, 2*xc-x, y, color, alpha);
1702
+
1703
+ _PutPixelAlpha(surface, x, 2*yc-y, color, alpha);
1704
+ _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, alpha);
1705
+
1706
+ int i;
1707
+
1708
+ for (i = 1; i <= dxt; i++)
1709
+ {
1710
+ x--;
1711
+ d += t - b2;
1712
+
1713
+ if (d >= 0)
1714
+ ys = y - 1;
1715
+ else if ((d - s - a2) > 0)
1716
+ {
1717
+ if ((2 * d - s - a2) >= 0)
1718
+ ys = y + 1;
1719
+ else
1720
+ {
1721
+ ys = y;
1722
+ y++;
1723
+ d -= s + a2;
1724
+ s += ds;
1725
+ }
1726
+ }
1727
+ else
1728
+ {
1729
+ y++;
1730
+ ys = y + 1;
1731
+ d -= s + a2;
1732
+ s += ds;
1733
+ }
1734
+
1735
+ t -= dt;
1736
+
1737
+ /* Calculate alpha */
1738
+ cp = float(abs(d)) / abs(s);
1739
+ is = float( cp * imax + 0.1 );
1740
+ ip = float( imax - is + 0.2 );
1741
+
1742
+ /* Overflow check */
1743
+ if( is > 1.0 )
1744
+ is = 1.0;
1745
+ if( ip > 1.0 )
1746
+ ip = 1.0;
1747
+
1748
+ /* Calculate alpha level */
1749
+ s_alpha = Uint8(is*255);
1750
+ p_alpha = Uint8(ip*255);
1751
+ if( alpha != 255 ){
1752
+ s_alpha = Uint8(s_alpha*alpha_pp);
1753
+ p_alpha = Uint8(p_alpha*alpha_pp);
1754
+ }
1755
+
1756
+
1757
+ /* Upper half */
1758
+ _PutPixelAlpha(surface, x, y, color, p_alpha);
1759
+ _PutPixelAlpha(surface, 2*xc-x, y, color, p_alpha);
1760
+
1761
+ _PutPixelAlpha(surface, x, ys, color, s_alpha);
1762
+ _PutPixelAlpha(surface, 2*xc-x, ys, color, s_alpha);
1763
+
1764
+
1765
+ /* Lower half */
1766
+ _PutPixelAlpha(surface, x, 2*yc-y, color, p_alpha);
1767
+ _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, p_alpha);
1768
+
1769
+ _PutPixelAlpha(surface, x, 2*yc-ys, color, s_alpha);
1770
+ _PutPixelAlpha(surface, 2*xc-x, 2*yc-ys, color, s_alpha);
1771
+ }
1772
+
1773
+ dyt = abs(y - yc);
1774
+
1775
+ for (i = 1; i <= dyt; i++)
1776
+ {
1777
+ y++;
1778
+ d -= s + a2;
1779
+
1780
+ if (d <= 0)
1781
+ xs = x + 1;
1782
+ else if ((d + t - b2) < 0)
1783
+ {
1784
+ if ((2 * d + t - b2) <= 0)
1785
+ xs = x - 1;
1786
+ else
1787
+ {
1788
+ xs = x;
1789
+ x--;
1790
+ d += t - b2;
1791
+ t -= dt;
1792
+ }
1793
+ }
1794
+ else
1795
+ {
1796
+ x--;
1797
+ xs = x - 1;
1798
+ d += t - b2;
1799
+ t -= dt;
1800
+ }
1801
+
1802
+ s += ds;
1803
+
1804
+ /* Calculate alpha */
1805
+ cp = float(abs(d)) / abs(t);
1806
+ is = float( cp * imax + 0.1 );
1807
+ ip = float( imax - is + 0.2 );
1808
+
1809
+ /* Overflow check */
1810
+ if( is > 1.0 )
1811
+ is = 1.0;
1812
+ if( ip > 1.0 )
1813
+ ip = 1.0;
1814
+
1815
+ /* Calculate alpha level */
1816
+ s_alpha = Uint8(is*255);
1817
+ p_alpha = Uint8(ip*255);
1818
+ if( alpha != 255 ){
1819
+ s_alpha = Uint8(s_alpha*alpha_pp);
1820
+ p_alpha = Uint8(p_alpha*alpha_pp);
1821
+ }
1822
+
1823
+
1824
+ /* Upper half */
1825
+ _PutPixelAlpha(surface, x, y, color, p_alpha);
1826
+ _PutPixelAlpha(surface, 2*xc-x, y, color, p_alpha);
1827
+
1828
+ _PutPixelAlpha(surface, xs, y, color, s_alpha);
1829
+ _PutPixelAlpha(surface, 2*xc-xs, y, color, s_alpha);
1830
+
1831
+
1832
+ /* Lower half*/
1833
+ _PutPixelAlpha(surface, x, 2*yc-y, color, p_alpha);
1834
+ _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, p_alpha);
1835
+
1836
+ _PutPixelAlpha(surface, xs, 2*yc-y, color, s_alpha);
1837
+ _PutPixelAlpha(surface, 2*xc-xs, 2*yc-y, color, s_alpha);
1838
+ }
1839
+
1840
+ /* unlock surface */
1841
+ if (SDL_MUSTLOCK(surface) && _sge_lock) {
1842
+ SDL_UnlockSurface(surface);
1843
+ }
1844
+
1845
+ /* Update surface if needed */
1846
+ sge_UpdateRect(surface, xc-rx, yc-ry, 2*rx+1, 2*ry+1);
1847
+ }
1848
+
1849
+
1850
+ //==================================================================================
1851
+ // Draws an anti-aliased ellipse (alpha - RGB)
1852
+ //==================================================================================
1853
+ void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
1854
+ {
1855
+ sge_AAEllipseAlpha(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B),alpha);
1856
+ }
1857
+
1858
+
1859
+ //==================================================================================
1860
+ // Draws an anti-aliased ellipse
1861
+ //==================================================================================
1862
+ void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color)
1863
+ {
1864
+ sge_AAEllipseAlpha(surface,xc,yc,rx,ry,color,255);
1865
+ }
1866
+
1867
+ //==================================================================================
1868
+ // Draws an anti-aliased ellipse (RGB)
1869
+ //==================================================================================
1870
+ void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
1871
+ {
1872
+ sge_AAEllipseAlpha(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B),255);
1873
+ }
1874
+
1875
+
1876
+ //==================================================================================
1877
+ // Draws a filled anti-aliased ellipse
1878
+ // This is just a quick hack...
1879
+ //==================================================================================
1880
+ void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color)
1881
+ {
1882
+ /* Sanity check */
1883
+ if (rx < 1)
1884
+ rx = 1;
1885
+ if (ry < 1)
1886
+ ry = 1;
1887
+
1888
+ int a2 = rx * rx;
1889
+ int b2 = ry * ry;
1890
+
1891
+ int ds = 2 * a2;
1892
+ int dt = 2 * b2;
1893
+
1894
+ int dxt = int (a2 / sqrt(a2 + b2));
1895
+
1896
+ int t = 0;
1897
+ int s = -2 * a2 * ry;
1898
+ int d = 0;
1899
+
1900
+ Sint16 x = xc;
1901
+ Sint16 y = yc - ry;
1902
+
1903
+ Sint16 xs, ys, dyt;
1904
+ float cp, is, ip, imax = 1.0;
1905
+
1906
+
1907
+ /* Lock surface */
1908
+ if ( SDL_MUSTLOCK(surface) && _sge_lock )
1909
+ if ( SDL_LockSurface(surface) < 0 )
1910
+ return;
1911
+
1912
+ /* "End points" */
1913
+ _PutPixel(surface, x, y, color);
1914
+ _PutPixel(surface, 2*xc-x, y, color);
1915
+
1916
+ _PutPixel(surface, x, 2*yc-y, color);
1917
+ _PutPixel(surface, 2*xc-x, 2*yc-y, color);
1918
+
1919
+ /* unlock surface */
1920
+ if (SDL_MUSTLOCK(surface) && _sge_lock)
1921
+ SDL_UnlockSurface(surface);
1922
+
1923
+ _VLine(surface, x, y+1, 2*yc-y-1, color);
1924
+
1925
+ int i;
1926
+
1927
+ for (i = 1; i <= dxt; i++)
1928
+ {
1929
+ x--;
1930
+ d += t - b2;
1931
+
1932
+ if (d >= 0)
1933
+ ys = y - 1;
1934
+ else if ((d - s - a2) > 0)
1935
+ {
1936
+ if ((2 * d - s - a2) >= 0)
1937
+ ys = y + 1;
1938
+ else
1939
+ {
1940
+ ys = y;
1941
+ y++;
1942
+ d -= s + a2;
1943
+ s += ds;
1944
+ }
1945
+ }
1946
+ else
1947
+ {
1948
+ y++;
1949
+ ys = y + 1;
1950
+ d -= s + a2;
1951
+ s += ds;
1952
+ }
1953
+
1954
+ t -= dt;
1955
+
1956
+ /* Calculate alpha */
1957
+ cp = (float) abs(d) / abs(s);
1958
+ is = cp * imax;
1959
+ ip = imax - is;
1960
+
1961
+
1962
+ /* Lock surface */
1963
+ if ( SDL_MUSTLOCK(surface) && _sge_lock )
1964
+ if ( SDL_LockSurface(surface) < 0 )
1965
+ return;
1966
+
1967
+ /* Upper half */
1968
+ _PutPixelAlpha(surface, x, y, color, Uint8(ip*255));
1969
+ _PutPixelAlpha(surface, 2*xc-x, y, color, Uint8(ip*255));
1970
+
1971
+ _PutPixelAlpha(surface, x, ys, color, Uint8(is*255));
1972
+ _PutPixelAlpha(surface, 2*xc-x, ys, color, Uint8(is*255));
1973
+
1974
+
1975
+ /* Lower half */
1976
+ _PutPixelAlpha(surface, x, 2*yc-y, color, Uint8(ip*255));
1977
+ _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, Uint8(ip*255));
1978
+
1979
+ _PutPixelAlpha(surface, x, 2*yc-ys, color, Uint8(is*255));
1980
+ _PutPixelAlpha(surface, 2*xc-x, 2*yc-ys, color, Uint8(is*255));
1981
+
1982
+ /* unlock surface */
1983
+ if (SDL_MUSTLOCK(surface) && _sge_lock)
1984
+ SDL_UnlockSurface(surface);
1985
+
1986
+
1987
+ /* Fill */
1988
+ _VLine(surface, x, y+1, 2*yc-y-1, color);
1989
+ _VLine(surface, 2*xc-x, y+1, 2*yc-y-1, color);
1990
+ _VLine(surface, x, ys+1, 2*yc-ys-1, color);
1991
+ _VLine(surface, 2*xc-x, ys+1, 2*yc-ys-1, color);
1992
+ }
1993
+
1994
+ dyt = abs(y - yc);
1995
+
1996
+ for (i = 1; i <= dyt; i++)
1997
+ {
1998
+ y++;
1999
+ d -= s + a2;
2000
+
2001
+ if (d <= 0)
2002
+ xs = x + 1;
2003
+ else if ((d + t - b2) < 0)
2004
+ {
2005
+ if ((2 * d + t - b2) <= 0)
2006
+ xs = x - 1;
2007
+ else
2008
+ {
2009
+ xs = x;
2010
+ x--;
2011
+ d += t - b2;
2012
+ t -= dt;
2013
+ }
2014
+ }
2015
+ else
2016
+ {
2017
+ x--;
2018
+ xs = x - 1;
2019
+ d += t - b2;
2020
+ t -= dt;
2021
+ }
2022
+
2023
+ s += ds;
2024
+
2025
+ /* Calculate alpha */
2026
+ cp = (float) abs(d) / abs(t);
2027
+ is = cp * imax;
2028
+ ip = imax - is;
2029
+
2030
+
2031
+ /* Lock surface */
2032
+ if ( SDL_MUSTLOCK(surface) && _sge_lock )
2033
+ if ( SDL_LockSurface(surface) < 0 )
2034
+ return;
2035
+
2036
+ /* Upper half */
2037
+ _PutPixelAlpha(surface, x, y, color, Uint8(ip*255));
2038
+ _PutPixelAlpha(surface, 2*xc-x, y, color, Uint8(ip*255));
2039
+
2040
+ _PutPixelAlpha(surface, xs, y, color, Uint8(is*255));
2041
+ _PutPixelAlpha(surface, 2*xc-xs, y, color, Uint8(is*255));
2042
+
2043
+
2044
+ /* Lower half*/
2045
+ _PutPixelAlpha(surface, x, 2*yc-y, color, Uint8(ip*255));
2046
+ _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, Uint8(ip*255));
2047
+
2048
+ _PutPixelAlpha(surface, xs, 2*yc-y, color, Uint8(is*255));
2049
+ _PutPixelAlpha(surface, 2*xc-xs, 2*yc-y, color, Uint8(is*255));
2050
+
2051
+ /* unlock surface */
2052
+ if (SDL_MUSTLOCK(surface) && _sge_lock)
2053
+ SDL_UnlockSurface(surface);
2054
+
2055
+ /* Fill */
2056
+ _HLine(surface, x+1, 2*xc-x-1, y, color);
2057
+ _HLine(surface, xs+1, 2*xc-xs-1, y, color);
2058
+ _HLine(surface, x+1, 2*xc-x-1, 2*yc-y, color);
2059
+ _HLine(surface, xs+1, 2*xc-xs-1, 2*yc-y, color);
2060
+ }
2061
+
2062
+ /* Update surface if needed */
2063
+ sge_UpdateRect(surface, xc-rx, yc-ry, 2*rx+1, 2*ry+1);
2064
+ }
2065
+
2066
+
2067
+ //==================================================================================
2068
+ // Draws a filled anti-aliased ellipse (RGB)
2069
+ //==================================================================================
2070
+ void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
2071
+ {
2072
+ sge_AAFilledEllipse(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B));
2073
+ }
2074
+
2075
+
2076
+
2077
+
2078
+
2079
+ //==================================================================================
2080
+ // Performs Callback at each circle point.
2081
+ //==================================================================================
2082
+ void sge_DoCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
2083
+ {
2084
+ Sint16 cx = 0;
2085
+ Sint16 cy = r;
2086
+ Sint16 df = 1 - r;
2087
+ Sint16 d_e = 3;
2088
+ Sint16 d_se = -2 * r + 5;
2089
+
2090
+ do {
2091
+ Callback(Surface, x+cx, y+cy, color);
2092
+ Callback(Surface, x-cx, y+cy, color);
2093
+ Callback(Surface, x+cx, y-cy, color);
2094
+ Callback(Surface, x-cx, y-cy, color);
2095
+ Callback(Surface, x+cy, y+cx, color);
2096
+ Callback(Surface, x+cy, y-cx, color);
2097
+ Callback(Surface, x-cy, y+cx, color);
2098
+ Callback(Surface, x-cy, y-cx, color);
2099
+
2100
+ if (df < 0) {
2101
+ df += d_e;
2102
+ d_e += 2;
2103
+ d_se += 2;
2104
+ }
2105
+ else {
2106
+ df += d_se;
2107
+ d_e += 2;
2108
+ d_se += 4;
2109
+ cy--;
2110
+ }
2111
+
2112
+ cx++;
2113
+
2114
+ }while(cx <= cy);
2115
+
2116
+ }
2117
+
2118
+
2119
+ //==================================================================================
2120
+ // Performs Callback at each circle point. (RGB)
2121
+ //==================================================================================
2122
+ void sge_DoCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
2123
+ {
2124
+ sge_DoCircle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),Callback);
2125
+ }
2126
+
2127
+
2128
+ //==================================================================================
2129
+ // Draws a circle
2130
+ //==================================================================================
2131
+ void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
2132
+ {
2133
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
2134
+ if (SDL_LockSurface(Surface) < 0)
2135
+ return;
2136
+ }
2137
+
2138
+ sge_DoCircle(Surface, x, y, r, color, _PutPixel);
2139
+
2140
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
2141
+ SDL_UnlockSurface(Surface);
2142
+ }
2143
+
2144
+ sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
2145
+ }
2146
+
2147
+ //==================================================================================
2148
+ // Draws a circle (RGB)
2149
+ //==================================================================================
2150
+ void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
2151
+ {
2152
+ sge_Circle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B));
2153
+ }
2154
+
2155
+
2156
+ //==================================================================================
2157
+ // Draws a circle (alpha)
2158
+ //==================================================================================
2159
+ void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha)
2160
+ {
2161
+ if (SDL_MUSTLOCK(Surface) && _sge_lock)
2162
+ if (SDL_LockSurface(Surface) < 0)
2163
+ return;
2164
+
2165
+ _sge_alpha_hack = alpha;
2166
+ sge_DoCircle(Surface, x, y, r, color, callback_alpha_hack);
2167
+
2168
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
2169
+ SDL_UnlockSurface(Surface);
2170
+ }
2171
+
2172
+ sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
2173
+ }
2174
+
2175
+ //==================================================================================
2176
+ // Draws a circle (alpha - RGB)
2177
+ //==================================================================================
2178
+ void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
2179
+ {
2180
+ sge_CircleAlpha(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),alpha);
2181
+ }
2182
+
2183
+
2184
+ //==================================================================================
2185
+ // Draws a filled circle
2186
+ //==================================================================================
2187
+ void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
2188
+ {
2189
+ Sint16 cx = 0;
2190
+ Sint16 cy = r;
2191
+ bool draw=true;
2192
+ Sint16 df = 1 - r;
2193
+ Sint16 d_e = 3;
2194
+ Sint16 d_se = -2 * r + 5;
2195
+
2196
+ do {
2197
+ if(draw){
2198
+ _HLine(Surface,x-cx,x+cx,y+cy,color);
2199
+ _HLine(Surface,x-cx,x+cx,y-cy,color);
2200
+ draw=false;
2201
+ }
2202
+ if(cx!=cy){
2203
+ if(cx){
2204
+ _HLine(Surface,x-cy,x+cy,y-cx,color);
2205
+ _HLine(Surface,x-cy,x+cy,y+cx,color);
2206
+ }else
2207
+ _HLine(Surface,x-cy,x+cy,y,color);
2208
+ }
2209
+
2210
+ if (df < 0) {
2211
+ df += d_e;
2212
+ d_e += 2;
2213
+ d_se += 2;
2214
+ }
2215
+ else {
2216
+ df += d_se;
2217
+ d_e += 2;
2218
+ d_se += 4;
2219
+ cy--;
2220
+ draw=true;
2221
+ }
2222
+ cx++;
2223
+ }while(cx <= cy);
2224
+
2225
+ sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
2226
+ }
2227
+
2228
+ //==================================================================================
2229
+ // Draws a filled circle (RGB)
2230
+ //==================================================================================
2231
+ void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
2232
+ {
2233
+ sge_FilledCircle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B));
2234
+ }
2235
+
2236
+
2237
+ //==================================================================================
2238
+ // Draws a filled circle (alpha)
2239
+ //==================================================================================
2240
+ void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha)
2241
+ {
2242
+ Sint16 cx = 0;
2243
+ Sint16 cy = r;
2244
+ bool draw=true;
2245
+ Sint16 df = 1 - r;
2246
+ Sint16 d_e = 3;
2247
+ Sint16 d_se = -2 * r + 5;
2248
+
2249
+ if (SDL_MUSTLOCK(Surface) && _sge_lock)
2250
+ if (SDL_LockSurface(Surface) < 0)
2251
+ return;
2252
+
2253
+ do {
2254
+ if(draw){
2255
+ _HLineAlpha(Surface,x-cx,x+cx,y+cy,color,alpha);
2256
+ _HLineAlpha(Surface,x-cx,x+cx,y-cy,color,alpha);
2257
+ draw=false;
2258
+ }
2259
+ if(cx!=cy){
2260
+ if(cx){
2261
+ _HLineAlpha(Surface,x-cy,x+cy,y-cx,color,alpha);
2262
+ _HLineAlpha(Surface,x-cy,x+cy,y+cx,color,alpha);
2263
+ }else
2264
+ _HLineAlpha(Surface,x-cy,x+cy,y,color,alpha);
2265
+ }
2266
+
2267
+ if (df < 0) {
2268
+ df += d_e;
2269
+ d_e += 2;
2270
+ d_se += 2;
2271
+ }
2272
+ else {
2273
+ df += d_se;
2274
+ d_e += 2;
2275
+ d_se += 4;
2276
+ cy--;
2277
+ draw=true;
2278
+ }
2279
+ cx++;
2280
+ }while(cx <= cy);
2281
+
2282
+ if (SDL_MUSTLOCK(Surface) && _sge_lock) {
2283
+ SDL_UnlockSurface(Surface);
2284
+ }
2285
+
2286
+ sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
2287
+ }
2288
+
2289
+ //==================================================================================
2290
+ // Draws a filled circle (alpha - RGB)
2291
+ //==================================================================================
2292
+ void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
2293
+ {
2294
+ sge_FilledCircleAlpha(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),alpha);
2295
+ }
2296
+
2297
+
2298
+ //==================================================================================
2299
+ // Draws an anti-aliased circle (alpha)
2300
+ //==================================================================================
2301
+ void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color, Uint8 alpha)
2302
+ {
2303
+ sge_AAEllipseAlpha(surface, xc, yc, r, r, color, alpha);
2304
+ }
2305
+
2306
+
2307
+ //==================================================================================
2308
+ // Draws an anti-aliased circle (alpha - RGB)
2309
+ //==================================================================================
2310
+ void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
2311
+ {
2312
+ sge_AAEllipseAlpha(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B),alpha);
2313
+ }
2314
+
2315
+
2316
+ //==================================================================================
2317
+ // Draws an anti-aliased circle
2318
+ //==================================================================================
2319
+ void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color)
2320
+ {
2321
+ sge_AAEllipseAlpha(surface,xc,yc,r,r,color,255);
2322
+ }
2323
+
2324
+ //==================================================================================
2325
+ // Draws an anti-aliased circle (RGB)
2326
+ //==================================================================================
2327
+ void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
2328
+ {
2329
+ sge_AAEllipseAlpha(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B),255);
2330
+ }
2331
+
2332
+
2333
+ //==================================================================================
2334
+ // Draws a filled anti-aliased circle
2335
+ //==================================================================================
2336
+ void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color)
2337
+ {
2338
+ sge_AAFilledEllipse(surface, xc, yc, r, r, color);
2339
+ }
2340
+
2341
+
2342
+ //==================================================================================
2343
+ // Draws a filled anti-aliased circle (RGB)
2344
+ //==================================================================================
2345
+ void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
2346
+ {
2347
+ sge_AAFilledEllipse(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B));
2348
+ }
2349
+
2350
+
2351
+
2352
+
2353
+
2354
+ //==================================================================================
2355
+ // Draws a bezier line
2356
+ //==================================================================================
2357
+ /* Macro to do the line... 'function' is the line drawing routine */
2358
+ #define DO_BEZIER(function)\
2359
+ /*
2360
+ * Note: I don't think there is any great performance win in translating this to fixed-point integer math,
2361
+ * most of the time is spent in the line drawing routine.
2362
+ */\
2363
+ float x = float(x1), y = float(y1);\
2364
+ float xp = x, yp = y;\
2365
+ float delta;\
2366
+ float dx, d2x, d3x;\
2367
+ float dy, d2y, d3y;\
2368
+ float a, b, c;\
2369
+ int i;\
2370
+ int n = 1;\
2371
+ Sint16 xmax=x1, ymax=y1, xmin=x1, ymin=y1;\
2372
+ \
2373
+ /* compute number of iterations */\
2374
+ if(level < 1)\
2375
+ level=1;\
2376
+ if(level >= 15)\
2377
+ level=15; \
2378
+ while (level-- > 0)\
2379
+ n*= 2;\
2380
+ delta = float( 1.0 / float(n) );\
2381
+ \
2382
+ /* compute finite differences */\
2383
+ /* a, b, c are the coefficient of the polynom in t defining the parametric curve */\
2384
+ /* The computation is done independently for x and y */\
2385
+ a = float(-x1 + 3*x2 - 3*x3 + x4);\
2386
+ b = float(3*x1 - 6*x2 + 3*x3);\
2387
+ c = float(-3*x1 + 3*x2);\
2388
+ \
2389
+ d3x = 6 * a * delta*delta*delta;\
2390
+ d2x = d3x + 2 * b * delta*delta;\
2391
+ dx = a * delta*delta*delta + b * delta*delta + c * delta;\
2392
+ \
2393
+ a = float(-y1 + 3*y2 - 3*y3 + y4);\
2394
+ b = float(3*y1 - 6*y2 + 3*y3);\
2395
+ c = float(-3*y1 + 3*y2);\
2396
+ \
2397
+ d3y = 6 * a * delta*delta*delta;\
2398
+ d2y = d3y + 2 * b * delta*delta;\
2399
+ dy = a * delta*delta*delta + b * delta*delta + c * delta;\
2400
+ \
2401
+ if (SDL_MUSTLOCK(surface) && _sge_lock) {\
2402
+ if (SDL_LockSurface(surface) < 0)\
2403
+ return;\
2404
+ }\
2405
+ \
2406
+ /* iterate */\
2407
+ for (i = 0; i < n; i++) {\
2408
+ x += dx; dx += d2x; d2x += d3x;\
2409
+ y += dy; dy += d2y; d2y += d3y;\
2410
+ if(Sint16(xp) != Sint16(x) || Sint16(yp) != Sint16(y)){\
2411
+ function;\
2412
+ if(_sge_update==1){\
2413
+ xmax= (xmax>Sint16(xp))? xmax : Sint16(xp); ymax= (ymax>Sint16(yp))? ymax : Sint16(yp);\
2414
+ xmin= (xmin<Sint16(xp))? xmin : Sint16(xp); ymin= (ymin<Sint16(yp))? ymin : Sint16(yp);\
2415
+ xmax= (xmax>Sint16(x))? xmax : Sint16(x); ymax= (ymax>Sint16(y))? ymax : Sint16(y);\
2416
+ xmin= (xmin<Sint16(x))? xmin : Sint16(x); ymin= (ymin<Sint16(y))? ymin : Sint16(y);\
2417
+ }\
2418
+ }\
2419
+ xp = x; yp = y;\
2420
+ }\
2421
+ \
2422
+ /* unlock the display */\
2423
+ if (SDL_MUSTLOCK(surface) && _sge_lock) {\
2424
+ SDL_UnlockSurface(surface);\
2425
+ }\
2426
+ \
2427
+ /* Update the area */\
2428
+ sge_UpdateRect(surface, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
2429
+
2430
+ //==================================================================================
2431
+ // Draws a bezier line
2432
+ //==================================================================================
2433
+ void sge_Bezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color)
2434
+ {
2435
+ DO_BEZIER(_Line(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color));
2436
+ }
2437
+
2438
+ //==================================================================================
2439
+ // Draws a bezier line (RGB)
2440
+ //==================================================================================
2441
+ void sge_Bezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B)
2442
+ {
2443
+ sge_Bezier(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B));
2444
+ }
2445
+
2446
+
2447
+ //==================================================================================
2448
+ // Draws a bezier line (alpha)
2449
+ //==================================================================================
2450
+ void sge_BezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color, Uint8 alpha)
2451
+ {
2452
+ _sge_alpha_hack = alpha;
2453
+
2454
+ DO_BEZIER(sge_DoLine(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color, callback_alpha_hack));
2455
+ }
2456
+
2457
+ //==================================================================================
2458
+ // Draws a bezier line (alpha - RGB)
2459
+ //==================================================================================
2460
+ void sge_BezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
2461
+ {
2462
+ sge_BezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),alpha);
2463
+ }
2464
+
2465
+
2466
+ //==================================================================================
2467
+ // Draws an AA bezier line (alpha)
2468
+ //==================================================================================
2469
+ void sge_AABezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color, Uint8 alpha)
2470
+ {
2471
+ Uint8 update = _sge_update;
2472
+ Uint8 lock = _sge_lock;
2473
+ _sge_update = 0;
2474
+ _sge_lock = 0;
2475
+
2476
+ if (SDL_MUSTLOCK(surface) && lock)
2477
+ if (SDL_LockSurface(surface) < 0)
2478
+ return;
2479
+
2480
+ DO_BEZIER(sge_AALineAlpha(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color, alpha));
2481
+
2482
+ if (SDL_MUSTLOCK(surface) && lock) {
2483
+ SDL_UnlockSurface(surface);
2484
+ }
2485
+
2486
+ _sge_update = update;
2487
+ _sge_lock = lock;
2488
+
2489
+ sge_UpdateRect(surface, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
2490
+ }
2491
+
2492
+ //==================================================================================
2493
+ // Draws an AA bezier line (alpha - RGB)
2494
+ //==================================================================================
2495
+ void sge_AABezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
2496
+ {
2497
+ sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),alpha);
2498
+ }
2499
+
2500
+
2501
+ //==================================================================================
2502
+ // Draws an AA bezier line
2503
+ //==================================================================================
2504
+ void sge_AABezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color)
2505
+ {
2506
+ sge_AABezierAlpha(surface, x1,y1, x2,y2, x3,y3, x4,y4, level, color, 255);
2507
+ }
2508
+
2509
+ //==================================================================================
2510
+ // Draws an AA bezier line (RGB)
2511
+ //==================================================================================
2512
+ void sge_AABezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B)
2513
+ {
2514
+ sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),255);
2515
+ }
2516
+