graphics 1.0.0b1 → 1.0.0b4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|