1 /*--License:
2 Kyra Sprite Engine
3 Copyright Lee Thomason (Grinning Lizard Software) 2001-2005
4 www.grinninglizard.com/kyra
5 www.sourceforge.net/projects/kyra
6
7 Kyra is provided under the LGPL.
8
9 I kindly request you display a splash screen (provided in the HTML documentation)
10 to promote Kyra and acknowledge the software and everyone who has contributed to it,
11 but it is not required by the license.
12
13 --- LGPL License --
14
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 2.1 of the License, or (at your option) any later version.
19
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
24
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
29 The full text of the license can be found in lgpl.txt
30 */
31
32 #include "image.h"
33 #include "SDL.h"
34 #include "engine.h"
35 #include "../../grinliz/glgeometry.h"
36
37 using namespace grinliz;
38
39
KrImage()40 KrImage::KrImage()
41 {
42 for( int i=0; i<KR_MAX_WINDOWS; ++i )
43 {
44 wasVisibleAtLastFlush[i] = true;
45 // haveCacheRect[i] = false;
46 }
47 }
48
49
AddedtoTree()50 void KrImage::AddedtoTree()
51 {
52 KrImNode::AddedtoTree();
53 GLASSERT( bounds[0].IsValid() );
54 }
55
56
LeavingTree()57 void KrImage::LeavingTree()
58 {
59 GLASSERT( Engine() );
60 for( int i=0; i<Engine()->NumWindows(); ++i )
61 {
62 if ( wasVisibleAtLastFlush[i] )
63 {
64 Engine()->DirtyRectangle(i)->AddRectangle( bounds[i] );
65 }
66 }
67 KrImNode::LeavingTree();
68 }
69
70
FlushInvalid(int window,bool cache)71 void KrImage::FlushInvalid( int window, bool cache )
72 {
73 // This whole cache mess takes advantage that the 2 rectangles generated
74 // by a particular sprite will almost certainly overlap and can be treated
75 // as one. Cache the first. When the 2nd comes in, if they intersect, union
76 // together and add both. Else add seperately. Doesn't make much of a
77 // difference, pulling for now.
78 //
79 // if ( cache )
80 // {
81 // // Make sure our bounds get re-painted.
82 // if ( wasVisibleAtLastFlush[window] || IsVisible(window) )
83 // {
84 // GLASSERT( haveCacheRect[window] == false );
85 // haveCacheRect[window] = true;
86 // cacheRect[window] = bounds[window];
87 // }
88 // }
89 // else
90 // {
91 // if ( haveCacheRect[window] )
92 // {
93 // // Make sure our bounds get re-painted.
94 // if ( wasVisibleAtLastFlush[window] || IsVisible(window) )
95 // {
96 // if ( cacheRect[window].Intersect( bounds[window] ) )
97 // {
98 // cacheRect[window].DoUnion( bounds[window] );
99 // Engine()->DirtyRectangle(window)->AddRectangle( cacheRect[window] );
100 // }
101 // else
102 // {
103 // Engine()->DirtyRectangle(window)->AddRectangle( cacheRect[window] );
104 // Engine()->DirtyRectangle(window)->AddRectangle( bounds[window] );
105 // }
106 // }
107 // haveCacheRect[window] = false;
108 // }
109 // else
110 // {
111 // The entirety of "the old code."
112 // Make sure our bounds get re-painted.
113 //GLASSERT( bounds[window].IsValid() );
114 bool vis = IsVisible(window);
115 GLASSERT( !vis || bounds[window].IsValid() );
116
117 if ( wasVisibleAtLastFlush[window] || vis )
118 {
119 Engine()->DirtyRectangle(window)->AddRectangle( bounds[window] );
120 wasVisibleAtLastFlush[window] = vis;
121 }
122 // }
123 // }
124 }
125
126
CheckCollision(KrImage * other,int window)127 bool KrImage::CheckCollision( KrImage* other, int window )
128 {
129 // Only sprites and canvases collide.
130 if ( !( other->ToSprite() || other->ToCanvas() )
131 || !( this->ToSprite() || this->ToCanvas() ) )
132 {
133 return false;
134 }
135
136 // If the bounding boxes don't overlap, they don't collide.
137 if ( !this->Bounds( window ).Intersect( other->Bounds( window ) ) )
138 {
139 return false;
140 }
141
142 // Visiibily
143 if ( !this->IsVisible( window ) || !other->IsVisible( window ) )
144 {
145 return false;
146 }
147
148 // Transparency
149 if ( this->CompositeCForm( window ).Alpha() == 0
150 || other->CompositeCForm( window ).Alpha() == 0 )
151 {
152 return false;
153 }
154
155 // GLOUTPUT( "BoundingBoxPass: %s [%d,%d]-[%d,%d]\n",
156 // other->NodeName().c_str(),
157 // other->Bounds( 0 ).xmin,
158 // other->Bounds( 0 ).ymin,
159 // other->Bounds( 0 ).xmax,
160 // other->Bounds( 0 ).ymax );
161
162
163 // Not colliding with text is a good idea -- but I fear I'll be chasing
164 // special cases and widget behavior forever. So removing check.
165
166 // // Don't collide with text.
167 // if ( other->Parent()
168 // && other->Parent()->Parent()
169 // && other->Parent()->Parent()->ToTextBox() )
170 // {
171 // return false;
172 // }
173 // if ( this->Parent()
174 // && this->Parent()->Parent()
175 // && this->Parent()->Parent()->ToTextBox() )
176 // {
177 // return false;
178 // }
179
180 // The entire collision thing is base on a left-right model. Very important
181 // to get that correct.
182 KrImage* left = 0;
183 KrImage* right = 0;
184
185 if ( other->Bounds( window ).min.x > this->Bounds( window ).min.x )
186 {
187 right = other;
188 left = this;
189 }
190 else
191 {
192 right = this;
193 left = other;
194 }
195
196 KrCollisionMap *leftMap, *rightMap;
197
198 leftMap = left->Resource()->GetCollisionMap( left, window );
199 rightMap = right->Resource()->GetCollisionMap( right, window );
200
201 Rectangle2I isect = left->Bounds( window );
202 isect.DoIntersection( right->Bounds( window ) );
203
204 if ( leftMap && rightMap )
205 {
206 // Okay, we might actually collide after all that.
207 return leftMap->Collide( right->Bounds( window ).min.x - left->Bounds( window ).min.x,
208 right->Bounds( window ).min.y - left->Bounds( window ).min.y,
209 isect,
210 rightMap );
211
212 }
213 return false;
214 }
215
216
217