graphics 1.0.0b1 → 1.0.0b4

Sign up to get free protection for your applications and to get access to all the features.
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,111 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * Drawing primitives (header)
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
+ #ifndef sge_primitives_H
19
+ #define sge_primitives_H
20
+
21
+ #include "SDL.h"
22
+ #include "sge_internal.h"
23
+
24
+
25
+ #ifdef _SGE_C
26
+ extern "C" {
27
+ #endif
28
+ DECLSPEC void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color);
29
+ DECLSPEC void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha);
30
+ DECLSPEC void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color);
31
+ DECLSPEC void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha);
32
+ DECLSPEC 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));
33
+ DECLSPEC void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color);
34
+ DECLSPEC void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha);
35
+ DECLSPEC void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
36
+ DECLSPEC void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha);
37
+ DECLSPEC 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));
38
+ DECLSPEC 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);
39
+ DECLSPEC 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);
40
+ DECLSPEC 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);
41
+ DECLSPEC 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);
42
+
43
+ DECLSPEC void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
44
+ DECLSPEC void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha);
45
+ DECLSPEC void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
46
+ DECLSPEC void sge_FilledRectAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha);
47
+
48
+ DECLSPEC 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));
49
+ DECLSPEC void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color);
50
+ DECLSPEC void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 Alpha);
51
+ DECLSPEC void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color);
52
+ DECLSPEC void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha);
53
+ DECLSPEC void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha);
54
+ DECLSPEC void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color);
55
+ DECLSPEC void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color);
56
+
57
+ DECLSPEC 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));
58
+ DECLSPEC void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color);
59
+ DECLSPEC void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha);
60
+ DECLSPEC void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color);
61
+ DECLSPEC void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha);
62
+ DECLSPEC void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color, Uint8 alpha);
63
+ DECLSPEC void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color);
64
+ DECLSPEC void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color);
65
+
66
+ DECLSPEC 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);
67
+ DECLSPEC 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);
68
+ DECLSPEC 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);
69
+ DECLSPEC 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);
70
+ #ifdef _SGE_C
71
+ }
72
+ #endif
73
+
74
+ #ifndef sge_C_ONLY
75
+ DECLSPEC void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B);
76
+ DECLSPEC void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
77
+ DECLSPEC void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B);
78
+ DECLSPEC void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
79
+ DECLSPEC 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));
80
+ DECLSPEC void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B);
81
+ DECLSPEC void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
82
+ DECLSPEC void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b);
83
+ DECLSPEC void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha);
84
+ DECLSPEC void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B);
85
+ DECLSPEC void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
86
+ DECLSPEC void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B);
87
+ DECLSPEC void sge_FilledRectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
88
+ DECLSPEC 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));
89
+ DECLSPEC void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B);
90
+ DECLSPEC void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
91
+ DECLSPEC void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B);
92
+ DECLSPEC void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
93
+ DECLSPEC void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
94
+ DECLSPEC void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B);
95
+ DECLSPEC void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B);
96
+ DECLSPEC 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));
97
+ DECLSPEC void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B);
98
+ DECLSPEC void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
99
+ DECLSPEC void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B);
100
+ DECLSPEC void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
101
+ DECLSPEC void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
102
+ DECLSPEC void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B);
103
+ DECLSPEC void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B);
104
+ DECLSPEC 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);
105
+ DECLSPEC 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);
106
+ DECLSPEC 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);
107
+ DECLSPEC 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);
108
+ #endif /* sge_C_ONLY */
109
+
110
+
111
+ #endif /* sge_primitives_H */
@@ -0,0 +1,683 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * Rotation routines
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
+ #include "SDL.h"
19
+ #include <stdio.h>
20
+ #include <math.h>
21
+ #include "sge_rotation.h"
22
+ #include "sge_surface.h"
23
+ #include "sge_blib.h"
24
+
25
+ #define SWAP(x,y,temp) temp=x;x=y;y=temp
26
+
27
+ extern Uint8 _sge_update; //Declared in sge_draw.cpp
28
+ extern Uint8 _sge_lock;
29
+
30
+ SDL_Rect sge_transform_tmap(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale, Uint16 qx, Uint16 qy);
31
+
32
+
33
+ //==================================================================================
34
+ // Helper function to sge_transform()
35
+ // Returns the bounding box
36
+ //==================================================================================
37
+ void _calcRect(SDL_Surface *src, SDL_Surface *dst, float theta, float xscale, float yscale, Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Sint16 *xmin, Sint16 *ymin, Sint16 *xmax, Sint16 *ymax)
38
+ {
39
+ Sint16 x, y, rx, ry;
40
+
41
+ // Clip to src surface
42
+ Sint16 sxmin = sge_clip_xmin(src);
43
+ Sint16 sxmax = sge_clip_xmax(src);
44
+ Sint16 symin = sge_clip_ymin(src);
45
+ Sint16 symax = sge_clip_ymax(src);
46
+ Sint16 sx[]={sxmin, sxmax, sxmin, sxmax};
47
+ Sint16 sy[]={symin, symax, symax, symin};
48
+
49
+ // We don't really need fixed-point here
50
+ // but why not?
51
+ Sint32 const istx = Sint32((sin(theta)*xscale) * 8192.0); /* Inverse transform */
52
+ Sint32 const ictx = Sint32((cos(theta)*xscale) * 8192.2);
53
+ Sint32 const isty = Sint32((sin(theta)*yscale) * 8192.0);
54
+ Sint32 const icty = Sint32((cos(theta)*yscale) * 8192.2);
55
+
56
+ //Calculate the four corner points
57
+ for(int i=0; i<4; i++){
58
+ rx = sx[i] - px;
59
+ ry = sy[i] - py;
60
+
61
+ x = Sint16(((ictx*rx - isty*ry) >> 13) + qx);
62
+ y = Sint16(((icty*ry + istx*rx) >> 13) + qy);
63
+
64
+
65
+ if(i==0){
66
+ *xmax = *xmin = x;
67
+ *ymax = *ymin = y;
68
+ }else{
69
+ if(x>*xmax)
70
+ *xmax=x;
71
+ else if(x<*xmin)
72
+ *xmin=x;
73
+
74
+ if(y>*ymax)
75
+ *ymax=y;
76
+ else if(y<*ymin)
77
+ *ymin=y;
78
+ }
79
+ }
80
+
81
+ //Better safe than sorry...
82
+ *xmin -= 1;
83
+ *ymin -= 1;
84
+ *xmax += 1;
85
+ *ymax += 1;
86
+
87
+ //Clip to dst surface
88
+ if( !dst )
89
+ return;
90
+ if( *xmin < sge_clip_xmin(dst) )
91
+ *xmin = sge_clip_xmin(dst);
92
+ if( *xmax > sge_clip_xmax(dst) )
93
+ *xmax = sge_clip_xmax(dst);
94
+ if( *ymin < sge_clip_ymin(dst) )
95
+ *ymin = sge_clip_ymin(dst);
96
+ if( *ymax > sge_clip_ymax(dst) )
97
+ *ymax = sge_clip_ymax(dst);
98
+ }
99
+
100
+
101
+ /*==================================================================================
102
+ ** Rotate by angle about pivot (px,py) scale by scale and place at
103
+ ** position (qx,qy).
104
+ **
105
+ ** Transformation matrix application (rotated coords "R"):
106
+ **
107
+ ** / rx \ / cos(theta) sin(theta) \ / dx \
108
+ ** | | = | | | |
109
+ ** \ ry / \ -sin(theta) cos(theta) / \ dy /
110
+ **
111
+ ** => rx = cos(theta) dx + sin(theta) dy
112
+ ** ry = cos(theta) dy - sin(theta) dx
113
+ ** but represented as a fixed-point float using integer math
114
+ **
115
+ ** Developed with the help from Terry Hancock (hancock@earthlink.net)
116
+ **
117
+ **==================================================================================*/
118
+ // First we need some macros to handle different bpp
119
+ // I'm sorry about this...
120
+ #define TRANSFORM(UintXX, DIV) \
121
+ Sint32 const src_pitch=src->pitch/DIV; \
122
+ Sint32 const dst_pitch=dst->pitch/DIV; \
123
+ UintXX const *src_row = (UintXX *)src->pixels; \
124
+ UintXX *dst_row; \
125
+ \
126
+ for (y=ymin; y<ymax; y++){ \
127
+ dy = y - qy; \
128
+ \
129
+ sx = Sint32(ctdx + stx*dy + mx); /* Compute source anchor points */ \
130
+ sy = Sint32(cty*dy - stdx + my); \
131
+ \
132
+ /* Calculate pointer to dst surface */ \
133
+ dst_row = (UintXX *)dst->pixels + y*dst_pitch; \
134
+ \
135
+ for (x=xmin; x<xmax; x++){ \
136
+ rx=Sint16(sx >> 13); /* Convert from fixed-point */ \
137
+ ry=Sint16(sy >> 13); \
138
+ \
139
+ /* Make sure the source pixel is actually in the source image. */ \
140
+ if( (rx>=sxmin) && (rx<=sxmax) && (ry>=symin) && (ry<=symax) ) \
141
+ *(dst_row + x) = *(src_row + ry*src_pitch + rx); \
142
+ \
143
+ sx += ctx; /* Incremental transformations */ \
144
+ sy -= sty; \
145
+ } \
146
+ }
147
+
148
+
149
+ #define TRANSFORM_GENERIC \
150
+ Uint8 R, G, B, A; \
151
+ \
152
+ for (y=ymin; y<ymax; y++){ \
153
+ dy = y - qy; \
154
+ \
155
+ sx = Sint32(ctdx + stx*dy + mx); /* Compute source anchor points */ \
156
+ sy = Sint32(cty*dy - stdx + my); \
157
+ \
158
+ for (x=xmin; x<xmax; x++){ \
159
+ rx=Sint16(sx >> 13); /* Convert from fixed-point */ \
160
+ ry=Sint16(sy >> 13); \
161
+ \
162
+ /* Make sure the source pixel is actually in the source image. */ \
163
+ if( (rx>=sxmin) && (rx<=sxmax) && (ry>=symin) && (ry<=symax) ){ \
164
+ sge_GetRGBA(sge_GetPixel(src,rx,ry), src->format, &R, &G, &B, &A);\
165
+ _PutPixelX(dst,x,y,sge_MapRGBA(dst->format, R, G, B, A)); \
166
+ \
167
+ } \
168
+ sx += ctx; /* Incremental transformations */ \
169
+ sy -= sty; \
170
+ } \
171
+ }
172
+
173
+
174
+ // Interpolated transform
175
+ #define TRANSFORM_AA(UintXX, DIV) \
176
+ Sint32 const src_pitch=src->pitch/DIV; \
177
+ Sint32 const dst_pitch=dst->pitch/DIV; \
178
+ UintXX const *src_row = (UintXX *)src->pixels; \
179
+ UintXX *dst_row; \
180
+ UintXX c1, c2, c3, c4;\
181
+ Uint32 R, G, B, A=0; \
182
+ UintXX Rmask = src->format->Rmask, Gmask = src->format->Gmask, Bmask = src->format->Bmask, Amask = src->format->Amask;\
183
+ Uint32 wx, wy;\
184
+ Uint32 p1, p2, p3, p4;\
185
+ \
186
+ /*
187
+ * Interpolation:
188
+ * We calculate the distances from our point to the four nearest pixels, d1..d4.
189
+ * d(a,b) = sqrt(a�+b�) ~= 0.707(a+b) (Pythagoras (Taylor) expanded around (0.5;0.5))
190
+ *
191
+ * 1 wx 2
192
+ * *-|-* (+ = our point at (x,y))
193
+ * | | | (* = the four nearest pixels)
194
+ * wy --+ | wx = float(x) - int(x)
195
+ * | | wy = float(y) - int(y)
196
+ * *---*
197
+ * 3 4
198
+ * d1 = d(wx,wy) d2 = d(1-wx,wy) d3 = d(wx,1-wy) d4 = d(1-wx,1-wy)
199
+ * We now want to weight each pixels importance - it's vicinity to our point:
200
+ * w1=d4 w2=d3 w3=d2 w4=d1 (Yes it works... just think a bit about it)
201
+ *
202
+ * If the pixels have the colors c1..c4 then our point should have the color
203
+ * c = (w1*c1 + w2*c2 + w3*c3 + w4*c4)/(w1+w2+w3+w4) (the weighted average)
204
+ * but w1+w2+w3+w4 = 4*0.707 so we might as well write it as
205
+ * c = p1*c1 + p2*c2 + p3*c3 + p4*c4 where p1..p4 = (w1..w4)/(4*0.707)
206
+ *
207
+ * But p1..p4 are fixed point so we can just divide the fixed point constant!
208
+ * 8192/(4*0.71) = 2897 and we can skip 0.71 too (the division will cancel it everywhere)
209
+ * 8192/4 = 2048
210
+ *
211
+ * 020102: I changed the fixed-point representation for the variables in the weighted average
212
+ * to 24.7 to avoid problems with 32bit colors. Everything else is still 18.13. This
213
+ * does however not solve the problem with 32bit RGBA colors...
214
+ */\
215
+ \
216
+ Sint32 const one = 2048>>6; /* 1 in Fixed-point */ \
217
+ Sint32 const two = 2*2048>>6; /* 2 in Fixed-point */ \
218
+ \
219
+ for (y=ymin; y<ymax; y++){ \
220
+ dy = y - qy; \
221
+ \
222
+ sx = Sint32(ctdx + stx*dy + mx); /* Compute source anchor points */ \
223
+ sy = Sint32(cty*dy - stdx + my); \
224
+ \
225
+ /* Calculate pointer to dst surface */ \
226
+ dst_row = (UintXX *)dst->pixels + y*dst_pitch; \
227
+ \
228
+ for (x=xmin; x<xmax; x++){ \
229
+ rx=Sint16(sx >> 13); /* Convert from fixed-point */ \
230
+ ry=Sint16(sy >> 13); \
231
+ \
232
+ /* Make sure the source pixel is actually in the source image. */ \
233
+ if( (rx>=sxmin) && (rx+1<=sxmax) && (ry>=symin) && (ry+1<=symax) ){ \
234
+ wx = (sx & 0x00001FFF) >>8; /* (float(x) - int(x)) / 4 */ \
235
+ wy = (sy & 0x00001FFF) >>8;\
236
+ \
237
+ p4 = wx+wy;\
238
+ p3 = one-wx+wy;\
239
+ p2 = wx+one-wy;\
240
+ p1 = two-wx-wy;\
241
+ \
242
+ c1 = *(src_row + ry*src_pitch + rx);\
243
+ c2 = *(src_row + ry*src_pitch + rx+1);\
244
+ c3 = *(src_row + (ry+1)*src_pitch + rx);\
245
+ c4 = *(src_row + (ry+1)*src_pitch + rx+1);\
246
+ \
247
+ /* Calculate the average */\
248
+ R = ((p1*(c1 & Rmask) + p2*(c2 & Rmask) + p3*(c3 & Rmask) + p4*(c4 & Rmask))>>7) & Rmask;\
249
+ G = ((p1*(c1 & Gmask) + p2*(c2 & Gmask) + p3*(c3 & Gmask) + p4*(c4 & Gmask))>>7) & Gmask;\
250
+ B = ((p1*(c1 & Bmask) + p2*(c2 & Bmask) + p3*(c3 & Bmask) + p4*(c4 & Bmask))>>7) & Bmask;\
251
+ if(Amask)\
252
+ A = ((p1*(c1 & Amask) + p2*(c2 & Amask) + p3*(c3 & Amask) + p4*(c4 & Amask))>>7) & Amask;\
253
+ \
254
+ *(dst_row + x) = R | G | B | A;\
255
+ } \
256
+ sx += ctx; /* Incremental transformations */ \
257
+ sy -= sty; \
258
+ } \
259
+ }
260
+
261
+ #define TRANSFORM_GENERIC_AA \
262
+ Uint8 R, G, B, A, R1, G1, B1, A1=0, R2, G2, B2, A2=0, R3, G3, B3, A3=0, R4, G4, B4, A4=0; \
263
+ Sint32 wx, wy, p1, p2, p3, p4;\
264
+ \
265
+ Sint32 const one = 2048; /* 1 in Fixed-point */ \
266
+ Sint32 const two = 2*2048; /* 2 in Fixed-point */ \
267
+ \
268
+ for (y=ymin; y<ymax; y++){ \
269
+ dy = y - qy; \
270
+ \
271
+ sx = Sint32(ctdx + stx*dy + mx); /* Compute source anchor points */ \
272
+ sy = Sint32(cty*dy - stdx + my); \
273
+ \
274
+ for (x=xmin; x<xmax; x++){ \
275
+ rx=Sint16(sx >> 13); /* Convert from fixed-point */ \
276
+ ry=Sint16(sy >> 13); \
277
+ \
278
+ /* Make sure the source pixel is actually in the source image. */ \
279
+ if( (rx>=sxmin) && (rx+1<=sxmax) && (ry>=symin) && (ry+1<=symax) ){ \
280
+ wx = (sx & 0x00001FFF) >> 2; /* (float(x) - int(x)) / 4 */ \
281
+ wy = (sy & 0x00001FFF) >> 2;\
282
+ \
283
+ p4 = wx+wy;\
284
+ p3 = one-wx+wy;\
285
+ p2 = wx+one-wy;\
286
+ p1 = two-wx-wy;\
287
+ \
288
+ sge_GetRGBA(sge_GetPixel(src,rx, ry), src->format, &R1, &G1, &B1, &A1);\
289
+ sge_GetRGBA(sge_GetPixel(src,rx+1,ry), src->format, &R2, &G2, &B2, &A2);\
290
+ sge_GetRGBA(sge_GetPixel(src,rx, ry+1), src->format, &R3, &G3, &B3, &A3);\
291
+ sge_GetRGBA(sge_GetPixel(src,rx+1,ry+1), src->format, &R4, &G4, &B4, &A4);\
292
+ \
293
+ /* Calculate the average */\
294
+ R = (p1*R1 + p2*R2 + p3*R3 + p4*R4)>>13;\
295
+ G = (p1*G1 + p2*G2 + p3*G3 + p4*G4)>>13;\
296
+ B = (p1*B1 + p2*B2 + p3*B3 + p4*B4)>>13;\
297
+ A = (p1*A1 + p2*A2 + p3*A3 + p4*A4)>>13;\
298
+ \
299
+ _PutPixelX(dst,x,y,sge_MapRGBA(dst->format, R, G, B, A)); \
300
+ \
301
+ } \
302
+ sx += ctx; /* Incremental transformations */ \
303
+ sy -= sty; \
304
+ } \
305
+ }
306
+
307
+ // We get better performance if AA and normal rendering is seperated into two functions (better optimization).
308
+ // sge_transform() is used as a wrapper.
309
+
310
+ SDL_Rect sge_transformNorm(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale ,Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Uint8 flags)
311
+ {
312
+ Sint32 dy, sx, sy;
313
+ Sint16 x, y, rx, ry;
314
+ SDL_Rect r;
315
+ r.x = r.y = r.w = r.h = 0;
316
+
317
+ float theta = float(angle*PI/180.0); /* Convert to radians. */
318
+
319
+
320
+ // Here we use 18.13 fixed point integer math
321
+ // Sint32 should have 31 usable bits and one for sign
322
+ // 2^13 = 8192
323
+
324
+ // Check scales
325
+ Sint32 maxint = Sint32(pow(2, sizeof(Sint32)*8 - 1 - 13)); // 2^(31-13)
326
+
327
+ if( xscale == 0 || yscale == 0)
328
+ return r;
329
+
330
+ if( 8192.0/xscale > maxint )
331
+ xscale = float(8192.0/maxint);
332
+ else if( 8192.0/xscale < -maxint )
333
+ xscale = float(-8192.0/maxint);
334
+
335
+ if( 8192.0/yscale > maxint )
336
+ yscale = float(8192.0/maxint);
337
+ else if( 8192.0/yscale < -maxint )
338
+ yscale = float(-8192.0/maxint);
339
+
340
+
341
+ // Fixed-point equivalents
342
+ Sint32 const stx = Sint32((sin(theta)/xscale) * 8192.0);
343
+ Sint32 const ctx = Sint32((cos(theta)/xscale) * 8192.0);
344
+ Sint32 const sty = Sint32((sin(theta)/yscale) * 8192.0);
345
+ Sint32 const cty = Sint32((cos(theta)/yscale) * 8192.0);
346
+ Sint32 const mx = Sint32(px*8192.0);
347
+ Sint32 const my = Sint32(py*8192.0);
348
+
349
+ // Compute a bounding rectangle
350
+ Sint16 xmin=0, xmax=dst->w, ymin=0, ymax=dst->h;
351
+ _calcRect(src, dst, theta, xscale, yscale, px, py, qx, qy, &xmin,&ymin, &xmax,&ymax);
352
+
353
+ // Clip to src surface
354
+ Sint16 sxmin = sge_clip_xmin(src);
355
+ Sint16 sxmax = sge_clip_xmax(src);
356
+ Sint16 symin = sge_clip_ymin(src);
357
+ Sint16 symax = sge_clip_ymax(src);
358
+
359
+ // Some terms in the transform are constant
360
+ Sint32 const dx = xmin - qx;
361
+ Sint32 const ctdx = ctx*dx;
362
+ Sint32 const stdx = sty*dx;
363
+
364
+ // Lock surfaces... hopfully less than two needs locking!
365
+ if ( SDL_MUSTLOCK(src) && _sge_lock )
366
+ if ( SDL_LockSurface(src) < 0 )
367
+ return r;
368
+ if ( SDL_MUSTLOCK(dst) && _sge_lock ){
369
+ if ( SDL_LockSurface(dst) < 0 ){
370
+ if ( SDL_MUSTLOCK(src) && _sge_lock )
371
+ SDL_UnlockSurface(src);
372
+ return r;
373
+ }
374
+ }
375
+
376
+
377
+ // Use the correct bpp
378
+ if( src->format->BytesPerPixel == dst->format->BytesPerPixel && src->format->BytesPerPixel != 3 && !(flags&SGE_TSAFE) ){
379
+ switch( src->format->BytesPerPixel ){
380
+ case 1: { /* Assuming 8-bpp */
381
+ TRANSFORM(Uint8, 1)
382
+ }
383
+ break;
384
+ case 2: { /* Probably 15-bpp or 16-bpp */
385
+ TRANSFORM(Uint16, 2)
386
+ }
387
+ break;
388
+ case 4: { /* Probably 32-bpp */
389
+ TRANSFORM(Uint32, 4)
390
+ }
391
+ break;
392
+ }
393
+ }else{
394
+ TRANSFORM_GENERIC
395
+ }
396
+
397
+
398
+ // Unlock surfaces
399
+ if ( SDL_MUSTLOCK(src) && _sge_lock )
400
+ SDL_UnlockSurface(src);
401
+ if ( SDL_MUSTLOCK(dst) && _sge_lock )
402
+ SDL_UnlockSurface(dst);
403
+
404
+
405
+ //Return the bounding rectangle
406
+ r.x=xmin; r.y=ymin; r.w=xmax-xmin; r.h=ymax-ymin;
407
+ return r;
408
+ }
409
+
410
+
411
+ SDL_Rect sge_transformAA(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale ,Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Uint8 flags)
412
+ {
413
+ Sint32 dy, sx, sy;
414
+ Sint16 x, y, rx, ry;
415
+ SDL_Rect r;
416
+ r.x = r.y = r.w = r.h = 0;
417
+
418
+ float theta = float(angle*PI/180.0); /* Convert to radians. */
419
+
420
+
421
+ // Here we use 18.13 fixed point integer math
422
+ // Sint32 should have 31 usable bits and one for sign
423
+ // 2^13 = 8192
424
+
425
+ // Check scales
426
+ Sint32 maxint = Sint32(pow(2, sizeof(Sint32)*8 - 1 - 13)); // 2^(31-13)
427
+
428
+ if( xscale == 0 || yscale == 0)
429
+ return r;
430
+
431
+ if( 8192.0/xscale > maxint )
432
+ xscale = float(8192.0/maxint);
433
+ else if( 8192.0/xscale < -maxint )
434
+ xscale = float(-8192.0/maxint);
435
+
436
+ if( 8192.0/yscale > maxint )
437
+ yscale = float(8192.0/maxint);
438
+ else if( 8192.0/yscale < -maxint )
439
+ yscale = float(-8192.0/maxint);
440
+
441
+
442
+ // Fixed-point equivalents
443
+ Sint32 const stx = Sint32((sin(theta)/xscale) * 8192.0);
444
+ Sint32 const ctx = Sint32((cos(theta)/xscale) * 8192.0);
445
+ Sint32 const sty = Sint32((sin(theta)/yscale) * 8192.0);
446
+ Sint32 const cty = Sint32((cos(theta)/yscale) * 8192.0);
447
+ Sint32 const mx = Sint32(px*8192.0);
448
+ Sint32 const my = Sint32(py*8192.0);
449
+
450
+ // Compute a bounding rectangle
451
+ Sint16 xmin=0, xmax=dst->w, ymin=0, ymax=dst->h;
452
+ _calcRect(src, dst, theta, xscale, yscale, px, py, qx, qy, &xmin,&ymin, &xmax,&ymax);
453
+
454
+ // Clip to src surface
455
+ Sint16 sxmin = sge_clip_xmin(src);
456
+ Sint16 sxmax = sge_clip_xmax(src);
457
+ Sint16 symin = sge_clip_ymin(src);
458
+ Sint16 symax = sge_clip_ymax(src);
459
+
460
+ // Some terms in the transform are constant
461
+ Sint32 const dx = xmin - qx;
462
+ Sint32 const ctdx = ctx*dx;
463
+ Sint32 const stdx = sty*dx;
464
+
465
+ // Lock surfaces... hopfully less than two needs locking!
466
+ if ( SDL_MUSTLOCK(src) && _sge_lock )
467
+ if ( SDL_LockSurface(src) < 0 )
468
+ return r;
469
+ if ( SDL_MUSTLOCK(dst) && _sge_lock ){
470
+ if ( SDL_LockSurface(dst) < 0 ){
471
+ if ( SDL_MUSTLOCK(src) && _sge_lock )
472
+ SDL_UnlockSurface(src);
473
+ return r;
474
+ }
475
+ }
476
+
477
+
478
+ // Use the correct bpp
479
+ if( src->format->BytesPerPixel == dst->format->BytesPerPixel && src->format->BytesPerPixel != 3 && !(flags&SGE_TSAFE) ){
480
+ switch( src->format->BytesPerPixel ){
481
+ case 1: { /* Assuming 8-bpp */
482
+ //TRANSFORM_AA(Uint8, 1)
483
+ TRANSFORM_GENERIC_AA
484
+ }
485
+ break;
486
+ case 2: { /* Probably 15-bpp or 16-bpp */
487
+ TRANSFORM_AA(Uint16, 2)
488
+ }
489
+ break;
490
+ case 4: { /* Probably 32-bpp */
491
+ TRANSFORM_AA(Uint32, 4)
492
+ }
493
+ break;
494
+ }
495
+ }else{
496
+ TRANSFORM_GENERIC_AA
497
+ }
498
+
499
+
500
+ // Unlock surfaces
501
+ if ( SDL_MUSTLOCK(src) && _sge_lock )
502
+ SDL_UnlockSurface(src);
503
+ if ( SDL_MUSTLOCK(dst) && _sge_lock )
504
+ SDL_UnlockSurface(dst);
505
+
506
+ //Return the bounding rectangle
507
+ r.x=xmin; r.y=ymin; r.w=xmax-xmin; r.h=ymax-ymin;
508
+ return r;
509
+ }
510
+
511
+
512
+ SDL_Rect sge_transform(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale, Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Uint8 flags)
513
+ {
514
+ if(flags&SGE_TTMAP)
515
+ return sge_transform_tmap(src, dst, angle, xscale, yscale, qx, qy);
516
+ else{
517
+ if(flags&SGE_TAA)
518
+ return sge_transformAA(src, dst, angle, xscale, yscale, px, py, qx, qy, flags);
519
+ else
520
+ return sge_transformNorm(src, dst, angle, xscale, yscale, px, py, qx, qy, flags);
521
+ }
522
+ }
523
+
524
+
525
+ //==================================================================================
526
+ // Same as sge_transform() but returns an surface with the result
527
+ //==================================================================================
528
+ SDL_Surface *sge_transform_surface(SDL_Surface *src, Uint32 bcol, float angle, float xscale, float yscale, Uint8 flags)
529
+ {
530
+ float theta = float(angle*PI/180.0); /* Convert to radians. */
531
+
532
+ // Compute a bounding rectangle
533
+ Sint16 xmin=0, xmax=0, ymin=0, ymax=0;
534
+ _calcRect(src, NULL, theta, xscale, yscale, 0, 0, 0, 0, &xmin,&ymin, &xmax,&ymax);
535
+
536
+ Sint16 w = xmax-xmin+1;
537
+ Sint16 h = ymax-ymin+1;
538
+
539
+ Sint16 qx = -xmin;
540
+ Sint16 qy = -ymin;
541
+
542
+ SDL_Surface *dest;
543
+ dest = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
544
+ if(!dest)
545
+ return NULL;
546
+
547
+ sge_ClearSurface(dest,bcol); //Set background color
548
+
549
+ sge_transform(src, dest, angle, xscale, yscale, 0, 0, qx, qy, flags);
550
+
551
+ return dest;
552
+ }
553
+
554
+
555
+ //==================================================================================
556
+ // Rotate using texture mapping
557
+ //==================================================================================
558
+ SDL_Rect sge_transform_tmap(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale, Uint16 qx, Uint16 qy)
559
+ {
560
+ double rad;
561
+ double a=(sge_clip_xmax(src) - sge_clip_xmin(src))/2.0;
562
+ double b=(sge_clip_ymax(src) - sge_clip_ymin(src))/2.0;
563
+
564
+ double cosv, sinv;
565
+
566
+ //Get an exact value if possible
567
+ if(angle==0.0 || angle==360.0){
568
+ cosv=1; sinv=0;
569
+ }
570
+ else if(angle==90.0){
571
+ cosv=0; sinv=1;
572
+ }
573
+ else if(angle==180.0){
574
+ cosv=-1; sinv=0;
575
+ }
576
+ else if(angle==270.0){
577
+ cosv=0; sinv=-1;
578
+ }
579
+ else{ //Oh well
580
+ rad=angle*(PI/180.0); //Deg => rad
581
+ cosv=cos(rad); sinv=sin(rad);
582
+ }
583
+
584
+ //Precalculate as much as possible
585
+ double acosv=a*cosv*xscale, bcosv=b*cosv*yscale;
586
+ double asinv=a*sinv*xscale, bsinv=b*sinv*yscale;
587
+
588
+
589
+ /* Do the maths */
590
+ Sint16 xt[4],yt[4];
591
+
592
+ xt[0] = Sint16((-acosv+bsinv)+qx);
593
+ yt[0] = Sint16((-asinv-bcosv)+qy);
594
+
595
+ xt[1] = Sint16((acosv+bsinv)+qx);
596
+ yt[1] = Sint16((asinv-bcosv)+qy);
597
+
598
+ xt[2] = Sint16((-acosv-bsinv)+qx);
599
+ yt[2] = Sint16((-asinv+bcosv)+qy);
600
+
601
+ xt[3] = Sint16((acosv-bsinv)+qx);
602
+ yt[3] = Sint16((asinv+bcosv)+qy);
603
+
604
+
605
+ //Use a texture mapped rectangle
606
+ sge_TexturedRect(dst,xt[0],yt[0],xt[1],yt[1],xt[2],yt[2],xt[3],yt[3],src, sge_clip_xmin(src),sge_clip_ymin(src), sge_clip_xmax(src),sge_clip_ymin(src), sge_clip_xmin(src),sge_clip_ymax(src), sge_clip_xmax(src),sge_clip_ymax(src));
607
+
608
+ //Or maybe two trigons...
609
+ //sge_TexturedTrigon(dest,xt[0],yt[0],xt[1],yt[1],xt[2],yt[2],src, sge_clip_xmin(src),sge_clip_ymin(src), sge_clip_xmax(src),sge_clip_ymin(src), sge_clip_xmin(src),sge_clip_ymax(src));
610
+ //sge_TexturedTrigon(dest,xt[3],yt[3],xt[1],yt[1],xt[2],yt[2],src, sge_clip_xmax(src),sge_clip_ymax(src), sge_clip_xmax(src),sge_clip_ymin(src), sge_clip_xmin(src),sge_clip_ymax(src));
611
+
612
+ //For debug
613
+ //sge_Trigon(dest,xt[0],yt[0],xt[1],yt[1],xt[2],yt[2],SDL_MapRGB(dest->format,255,0,0));
614
+ //sge_Trigon(dest,xt[3],yt[3],xt[1],yt[1],xt[2],yt[2],SDL_MapRGB(dest->format,0,255,0));
615
+
616
+ Sint16 xmax=xt[0], xmin=xt[0];
617
+ xmax= (xmax>xt[1])? xmax : xt[1];
618
+ xmin= (xmin<xt[1])? xmin : xt[1];
619
+ xmax= (xmax>xt[2])? xmax : xt[2];
620
+ xmin= (xmin<xt[2])? xmin : xt[2];
621
+ xmax= (xmax>xt[3])? xmax : xt[3];
622
+ xmin= (xmin<xt[3])? xmin : xt[3];
623
+
624
+ Sint16 ymax=yt[0], ymin=yt[0];
625
+ ymax= (ymax>yt[1])? ymax : yt[1];
626
+ ymin= (ymin<yt[1])? ymin : yt[1];
627
+ ymax= (ymax>yt[2])? ymax : yt[2];
628
+ ymin= (ymin<yt[2])? ymin : yt[2];
629
+ ymax= (ymax>yt[3])? ymax : yt[3];
630
+ ymin= (ymin<yt[3])? ymin : yt[3];
631
+
632
+ SDL_Rect r;
633
+ r.x=xmin; r.y=ymin; r.w=xmax-xmin+1; r.h=ymax-ymin+1;
634
+ return r;
635
+ }
636
+
637
+
638
+
639
+ //==================================================================================
640
+ // Obsolete functions
641
+ //==================================================================================
642
+ SDL_Surface *sge_rotate_scaled_surface(SDL_Surface *src, int angle, double scale, Uint32 bcol)
643
+ {
644
+ SDL_Surface *dest;
645
+
646
+ /* Create the destination surface*/
647
+ int max = int( sqrt( (src->h*src->h/2 + src->w*src->w/2) *scale + 1 ) );
648
+ dest=SDL_AllocSurface(SDL_SWSURFACE, max, max, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask );
649
+ if(!dest){SDL_SetError("SGE - Out of memory");return NULL;}
650
+ sge_ClearSurface(dest,bcol);
651
+
652
+ sge_transform(src, dest, float(angle), float(scale), float(scale), src->w/2,src->h/2, dest->w/2,dest->h/2,0);
653
+
654
+ return(dest);
655
+ }
656
+
657
+ SDL_Surface *sge_rotate_surface(SDL_Surface *src, int angle, Uint32 bcol)
658
+ {
659
+ return sge_rotate_scaled_surface(src, angle, 1.0, bcol);
660
+ }
661
+
662
+ SDL_Rect sge_rotate_xyscaled(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle, double xscale, double yscale)
663
+ {
664
+ SDL_Rect ret;
665
+
666
+ ret=sge_transform(src, dest, float(angle), float(xscale), float(yscale), src->w/2,src->h/2, x,y,0);
667
+
668
+ if(_sge_update)
669
+ sge_UpdateRect(dest,ret.x,ret.y,ret.w+1,ret.h+1);
670
+
671
+ return ret;
672
+ }
673
+
674
+ SDL_Rect sge_rotate_scaled(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle, double scale)
675
+ {
676
+ return sge_rotate_xyscaled(dest,src,x,y,angle,scale,scale);
677
+ }
678
+
679
+ SDL_Rect sge_rotate(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle)
680
+ {
681
+ return sge_rotate_xyscaled(dest,src,x,y,angle,1.0,1.0);
682
+ }
683
+