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
33 #include "states.h"
34 #include "statemachine.h"
35 #include "../engine/painter.h"
36 #include "../engine/parser.h"
37 #include "SDL.h"
38 #include "../engine/engine.h"
39 #include "../engine/spriteresource.h"
40 #include "../engine/textbox.h"
41 #include "../engine/box.h"
42 #include "dom.h"
43
44
EdStateAlign(Editor * _machine)45 EdStateAlign::EdStateAlign( Editor* _machine ) : EdState( _machine )
46 {
47 alignNode = 0;
48 scale = 1;
49 }
50
51
StateOpening()52 void EdStateAlign::StateOpening()
53 {
54 shared->ConsoleNode()->SetVisible( false );
55 shared->SetInfoBox( false );
56
57 GLASSERT( shared->CurrentAction() );
58
59 spriteResource = 0;
60 alignNode = new KrImNode();
61 shared->Engine()->Tree()->AddNode( shared->ImNode(), alignNode );
62 spriteParent = new KrImNode();
63 shared->Engine()->Tree()->AddNode( alignNode, spriteParent );
64
65 // Create the action, put it in a sprite resource.
66 KrAction* action = shared->CreateAnimationAction();
67
68 if ( action )
69 {
70 spriteResource = new KrSpriteResource( "AlignerSprite" );
71 spriteResource->AddAction( action );
72
73 // Note that the first and last sprite is a duplicate at
74 // different locations.
75 numFrames = spriteResource->GetActionByIndex( 0 )->NumFrames();
76 currentFrame = 0;
77 adjustingFrame = ( numFrames + numFrames - 1 ) % numFrames;
78
79 for( int i=0; i <= numFrames; i++ )
80 {
81 KrSprite* sprite = new KrSprite( spriteResource );
82 sprite->SetFrame( i % numFrames );
83 sprite->SetNodeId( i + ID_OFFSET );
84 shared->Engine()->Tree()->AddNode( spriteParent,
85 sprite );
86 }
87 }
88
89 // Set up an output box:
90 KrFontResource* res = shared->Engine()->Vault()->GetFontResource( "CONSOLE" );
91 grinliz::Rectangle2I bounds = shared->Engine()->ScreenBounds();
92 alignInfo = new KrTextBox( res, bounds.Width(), bounds.Height(), 2 );
93 shared->Engine()->Tree()->AddNode( alignNode, alignInfo );
94
95 PositionSprites();
96
97 // restore the previous scale
98 spriteParent->SetScale( scale, scale );
99 }
100
101
StateClosing()102 void EdStateAlign::StateClosing()
103 {
104 shared->Engine()->Tree()->DeleteNode( alignNode );
105 delete spriteResource;
106 spriteResource = 0;
107 alignNode = 0;
108 shared->ConsoleNode()->SetVisible( true );
109 }
110
111
MotionKey(int key)112 void EdStateAlign::MotionKey( int key )
113 {
114 int i;
115 // We only every use the first action in the editor, so
116 // it is safe to use GetAction( 0 )
117 if ( key == SDLK_PAGEDOWN )
118 {
119 currentFrame = ( currentFrame + 1 ) % numFrames;
120 adjustingFrame = ( currentFrame + numFrames - 1 ) % numFrames;
121 }
122 else if ( key == SDLK_PAGEUP )
123 {
124 currentFrame = ( currentFrame + numFrames - 1 ) % numFrames;
125 adjustingFrame = ( currentFrame + numFrames - 1 ) % numFrames;
126 }
127 else
128 {
129 GlSListIterator< EdWidget* > it( shared->CurrentAction()->children );
130
131 for( i = 0, it.Begin();
132 !it.Done();
133 ++i, it.Next() )
134 {
135 if ( i == adjustingFrame )
136 {
137 EdWidgetFrame* widget = it.Current()->ToFrame();
138 GLASSERT( widget );
139 KrDom::Frame frameData = widget->GetFrameData();
140
141 switch ( key )
142 {
143 // The directions are reversed because we are
144 // adjusting the delta from the previous frame
145 // TO the current frame.
146 case SDLK_UP:
147 frameData.deltaY -= 1;
148 break;
149 case SDLK_DOWN:
150 frameData.deltaY += 1;
151 break;
152 case SDLK_LEFT:
153 frameData.deltaX -= 1;
154 break;
155 case SDLK_RIGHT:
156 frameData.deltaX += 1;
157 break;
158 }
159 widget->SetFrameData( frameData );
160 break;
161 }
162 }
163 }
164 PositionSprites();
165 }
166
167
PositionSprites()168 void EdStateAlign::PositionSprites()
169 {
170 int x, y, i;
171 KrImNode* krimNode;
172 KrImage* image;
173 KrColorTransform currentFrameColor;
174 KrColorTransform adjustingFrameColor;
175 KrColorTransform frameColor;
176
177 currentFrameColor.Brighten( 20 );
178 adjustingFrameColor.SetAlpha( 200 );
179 frameColor.SetAlpha( 50 );
180
181 // Walk the DOM and get the step information. Use this to set
182 // the sprite locations.
183
184 KrRect rect = shared->Engine()->ScreenBounds();
185 x = rect.Width() / 2;
186 y = rect.Height() / 2;
187 spriteParent->SetPos( x, y );
188 x = y = 0;
189
190 GlSListIterator< EdWidget* > it( shared->CurrentAction()->children );
191
192 for( i = 0, it.Begin();
193 !it.Done();
194 ++i, it.Next() )
195 {
196 krimNode = shared->Engine()->Tree()->FindNodeById( i + ID_OFFSET );
197 GLASSERT( krimNode );
198 image = krimNode->ToImage();
199 GLASSERT( image );
200
201 image->SetPos( x, y );
202 // the i not 0 case will be picked up by the extra frame.
203 if ( i != 0 && currentFrame == i )
204 {
205 image->SetColor( currentFrameColor );
206 image->SetZDepth( 3 );
207 }
208 else if ( i == adjustingFrame )
209 {
210 image->SetColor( adjustingFrameColor );
211 image->SetZDepth( 1 );
212 }
213 else
214 {
215 image->SetColor( frameColor );
216 image->SetZDepth( 0 );
217 }
218
219 x += it.Current()->ToFrame()->GetFrameData().deltaX;
220 y += it.Current()->ToFrame()->GetFrameData().deltaY;
221 }
222 // The one extra sprite
223 krimNode = shared->Engine()->Tree()->FindNodeById( i + ID_OFFSET );
224 GLASSERT( krimNode );
225 image = krimNode->ToImage();
226 GLASSERT( image );
227 image->SetPos( x, y );
228
229 if ( currentFrame == i-numFrames )
230 {
231 image->SetColor( currentFrameColor );
232 image->SetZDepth( 3 );
233 }
234 else if ( i == adjustingFrame )
235 {
236 image->SetColor( adjustingFrameColor );
237 image->SetZDepth( 1 );
238 }
239 else
240 {
241 image->SetColor( frameColor );
242 image->SetZDepth( 0 );
243 }
244
245 // Draw frame information (slap it on top of the engine output.)
246 // x = 0;
247 // y = 0;
248 int dx = 0;
249 int dy = 0;
250 char buf[ 64 ];
251
252 // Get the current and previous elements.
253 for( i = 0, it.Begin();
254 !it.Done();
255 ++i, it.Next() )
256 {
257 KrDom::Frame f;
258 f = it.Current()->ToFrame()->GetFrameData();
259
260 sprintf( buf, "%2d-->%2d dx=%3d dy=%3d %s\n",
261 i,
262 (i+1 ) % numFrames,
263 f.deltaX, f.deltaY,
264 i == adjustingFrame ? "*" : "" );
265
266 alignInfo->SetTextChar( buf, i );
267 dx += f.deltaX;
268 dy += f.deltaY;
269 }
270 sprintf( buf, "total dx=%2d dy=%2d\n", dx, dy );
271 alignInfo->SetTextChar( buf, i );
272 }
273
274
ZoomIn()275 void EdStateAlign::ZoomIn()
276 {
277 if ( scale < 4 )
278 {
279 scale *= 2;
280 spriteParent->SetScale( scale, scale );
281 }
282 }
283
284
ZoomOut()285 void EdStateAlign::ZoomOut()
286 {
287 if ( scale.v > GlFixed_1 / 4 )
288 {
289 scale /= 2;
290 spriteParent->SetScale( scale, scale );
291 }
292 }
293
294