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,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
+