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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +30 -0
- data/Manifest.txt +39 -7
- data/README.rdoc +48 -4
- data/Rakefile +8 -2
- data/examples/boid.rb +9 -18
- data/examples/bounce.rb +15 -23
- data/examples/canvas.rb +75 -0
- data/examples/collision.rb +6 -6
- data/examples/demo.rb +5 -7
- data/examples/editor.rb +12 -9
- data/examples/fluid.rb +2 -3
- data/examples/fluid2.rb +1 -1
- data/examples/{lito2.rb → gol.rb} +0 -0
- data/examples/{zenspider4.rb → gol2.rb} +0 -0
- data/examples/logo.rb +4 -7
- data/examples/maze.rb +136 -0
- data/examples/tank.rb +10 -11
- data/examples/tank2.rb +12 -17
- data/examples/targeting.rb +1 -1
- data/examples/vants.rb +1 -1
- data/examples/walker.rb +3 -12
- data/examples/walker2.rb +197 -0
- data/examples/zombies.rb +31 -35
- data/ext/sdl/extconf.rb +31 -0
- data/ext/sdl/sdl.c +1067 -0
- data/ext/sdl/sge/INSTALL +72 -0
- data/ext/sdl/sge/LICENSE +504 -0
- data/ext/sdl/sge/Makefile +83 -0
- data/ext/sdl/sge/Makefile.conf +63 -0
- data/ext/sdl/sge/README +219 -0
- data/ext/sdl/sge/Todo +7 -0
- data/ext/sdl/sge/WhatsNew +224 -0
- data/ext/sdl/sge/sge.h +31 -0
- data/ext/sdl/sge/sge_blib.cpp +1939 -0
- data/ext/sdl/sge/sge_blib.h +68 -0
- data/ext/sdl/sge/sge_bm_text.cpp +451 -0
- data/ext/sdl/sge/sge_bm_text.h +71 -0
- data/ext/sdl/sge/sge_collision.cpp +388 -0
- data/ext/sdl/sge/sge_collision.h +54 -0
- data/ext/sdl/sge/sge_config.h +6 -0
- data/ext/sdl/sge/sge_internal.h +152 -0
- data/ext/sdl/sge/sge_misc.cpp +92 -0
- data/ext/sdl/sge/sge_misc.h +37 -0
- data/ext/sdl/sge/sge_primitives.cpp +2516 -0
- data/ext/sdl/sge/sge_primitives.h +111 -0
- data/ext/sdl/sge/sge_rotation.cpp +683 -0
- data/ext/sdl/sge/sge_rotation.h +46 -0
- data/ext/sdl/sge/sge_shape.cpp +762 -0
- data/ext/sdl/sge/sge_shape.h +365 -0
- data/ext/sdl/sge/sge_surface.cpp +1090 -0
- data/ext/sdl/sge/sge_surface.h +100 -0
- data/ext/sdl/sge/sge_textpp.cpp +785 -0
- data/ext/sdl/sge/sge_textpp.h +270 -0
- data/ext/sdl/sge/sge_tt_text.cpp +1456 -0
- data/ext/sdl/sge/sge_tt_text.h +114 -0
- data/graphics_setup.sh +26 -0
- data/lib/graphics.rb +1 -1
- data/lib/graphics/body.rb +50 -3
- data/lib/graphics/extensions.rb +13 -7
- data/lib/graphics/simulation.rb +126 -46
- data/test/test_graphics.rb +52 -12
- data/test/test_sdl.rb +1 -0
- metadata +54 -23
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
- data/examples/lito.rb +0 -108
- data/examples/zenspider1.rb +0 -93
- data/examples/zenspider2.rb +0 -123
- data/examples/zenspider3.rb +0 -104
- 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
|
+
|