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