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 
34 #include "demos.h"
35 #include <math.h>
36 
37 using namespace grinliz;
38 
SinWaveTest(SDL_Surface * screen)39 SinWaveTest::SinWaveTest( SDL_Surface* screen )
40 {
41 	// The usual beginning: create the engine, load the dat file.
42 	engine = new KrEngine( screen );
43 	GLASSERT( engine );
44 	engine->FillBackground( 0 );
45 
46 	random.SetSeed( 0 );
47 
48 	if ( !engine->Vault()->LoadDatFile( "space.dat" ) )
49 	{
50 		GLOUTPUT(( "Error loading 'space.dat'\n" ));
51 		exit(100);
52 	}
53 
54 	// Get the resource from the dat file: we use the small
55 	// ship and the train ship.
56 	KrSpriteResource* smallRes = engine->Vault()->GetSpriteResource( "SMALL" );
57 	GLASSERT( smallRes );
58 	KrSpriteResource* trainRes = engine->Vault()->GetSpriteResource( "TRAIN" );
59 	GLASSERT( trainRes );
60 
61 	// A background starfield - same as the BEM one.
62 	AddStarfield();
63 
64 
65 	// Set up the horizontal ships.
66 	int i = 0, j = 0;
67 
68 	for( i=0; i<MAX_HORIZONTAL_SHIP; ++i )
69 	{
70 		horizontal[0][i] = new KrSprite( smallRes );
71 		horizontal[0][i]->SetPos( -PADDING + i * ( engine->ScreenBounds().Width() + PADDING * 2 ) / MAX_HORIZONTAL_SHIP,
72 								  1 * engine->ScreenBounds().Height() / 4 );
73 		engine->Tree()->AddNode( 0, horizontal[0][i] );
74 
75 
76 		horizontal[1][i] = new KrSprite( smallRes );
77 		horizontal[1][i]->SetPos( -PADDING + i * ( engine->ScreenBounds().Width() + PADDING * 2 ) / MAX_HORIZONTAL_SHIP,
78 								  3 * engine->ScreenBounds().Height() / 4 );
79 		engine->Tree()->AddNode( 0, horizontal[1][i] );
80 	}
81 
82 
83 	// Add the trains
84 	memset( vertical, 0, ROWS * (MAX_CARS + 2) * sizeof( KrSprite* ) );
85 	const int SPACE = 52;
86 	for ( i=0; i<ROWS; ++i )
87 	{
88 		// Engine
89 		int x = GetX( i );
90 		int y = random.Rand( engine->ScreenBounds().Height() );
91 		vertical[i][0] = new KrSprite( trainRes );
92 		vertical[i][0]->SetAction( "ENGINE" );
93 		vertical[i][0]->SetPos( x, y );
94 		engine->Tree()->AddNode( 0, vertical[i][0] );
95 
96 		// Cars
97 		for ( j=0; j<MAX_CARS; ++j )
98 		{
99 			KrSprite* car = new KrSprite( trainRes );
100 			car->SetAction( "CAR" );
101 			car->SetPos( x, y + SPACE * ( j + 1 ) );
102 			engine->Tree()->AddNode( 0, car );
103 			vertical[i][1+j] = car;
104 		}
105 
106 		// Caboose
107 		KrSprite* caboose = new KrSprite( trainRes );
108 		caboose->SetAction( "CABOOSE" );
109 		caboose->SetPos( x, y + SPACE * ( MAX_CARS + 1 ) );
110 		engine->Tree()->AddNode( 0, caboose );
111 		vertical[i][1+MAX_CARS] = caboose;
112 	}
113 	AddText( engine );
114 }
115 
116 
~SinWaveTest()117 SinWaveTest::~SinWaveTest()
118 {
119 	delete engine;
120 }
121 
122 
AddStarfield()123 void SinWaveTest::AddStarfield()
124 {
125 	int x, y;
126 	KrTileResource* starRes = engine->Vault()->GetTileResource( "STARS" );
127 	GLASSERT( starRes );
128 	KrRect field = engine->ScreenBounds();
129 
130  	for( x = field.min.x; x <= field.max.x; x += starRes->Size() )
131 	{
132 	 	for( y = field.min.y; y <= field.max.y; y += starRes->Size() )
133 		{
134 			KrTile* tile = new KrTile( starRes );
135 			GLASSERT( tile );
136 
137 			tile->SetRotation( random.Rand( 8 ) );
138 			tile->SetPos( x, y );
139 			engine->Tree()->AddNode( 0, tile );
140 		}
141 	}
142 }
143 
144 
CalculateScale(int _y)145 double SinWaveTest::CalculateScale( int _y )
146 {
147 	const double PI = 3.1415926535897932384626433832795;
148 	double y       = double( _y );
149 	double screenH = double( engine->ScreenBounds().Height() );
150 	double thetaRadians = ( y / screenH ) * PI;
151 
152 	double dScale = ( cos( thetaRadians ) * 0.5 + 1.0 ) * 0.8;
153 	return dScale;
154 }
155 
156 
CalculateTintFromScale(double scale)157 int SinWaveTest::CalculateTintFromScale( double scale )
158 {
159 	const double lowPoint  = ( 0.4 * 0.8 );
160 	const double highPoint = ( 1.5 * 0.8 );
161 
162 	int tint = int ( 180.0 + ( scale - lowPoint ) / ( highPoint - lowPoint ) * 75.0 );
163 	Clamp( tint, 0, 255 );
164 	return tint;
165 }
166 
167 
168 
DrawFrame()169 void SinWaveTest::DrawFrame()
170 {
171 	// Move the ships (based on current depth), set the new depth,
172 	// and set the scaling factor.
173 	KrSprite* sprite;
174     int i, j;
175 
176 	// The horizontal rows of ships.
177 	for( i=0; i<2; ++i )
178 	{
179 		for ( j=0; j<MAX_HORIZONTAL_SHIP; j++ )
180 		{
181 			sprite = horizontal[i][j];
182 			if ( sprite )
183 			{
184 				double dScale = ( i == 1 ) ? 1.2 : 0.4;
185 				int deltaX    = ( i == 0 ) ? 2 : 3;
186 
187 				sprite->SetPos( sprite->X() - deltaX, sprite->Y() );
188 				if ( sprite->X() < -PADDING ) sprite->SetPos( engine->ScreenBounds().Width() + PADDING, sprite->Y() );
189 
190 				GlFixed scale = dScale;
191 				sprite->SetScale( scale, scale );
192 				sprite->SetZDepth( scale.v );
193 
194 				KrColorTransform color;
195 				int tint = CalculateTintFromScale( dScale );
196 
197 				color.Set( tint, 0, tint, 0, tint, 0, 255 );
198 				sprite->SetColor( color );
199 			}
200 		}
201 	}
202 
203 
204 	// The trains.
205 	for( i=0; i<ROWS; ++i )
206 	{
207 		for ( j=0; j<MAX_CARS + 2; j++ )
208 		{
209 			sprite = vertical[i][j];
210 			if ( sprite )
211 			{
212 				int deltaY = 3;
213 
214 				sprite->SetPos( sprite->X(), sprite->Y() - deltaY );
215 				if ( j == MAX_CARS + 1 && sprite->Y() < 0 )
216 				{
217 					for( int k=0; k<MAX_CARS+2; ++k )
218 					{
219 						vertical[i][k]->SetPos( vertical[i][k]->X(),
220 												vertical[i][k]->Y() + engine->ScreenBounds().Height() * 2 );
221 					}
222 				}
223 
224 				// Recalc the scale based on the new position.
225 				double dScale = CalculateScale( sprite->Y() );
226 
227 				GlFixed scale = dScale;
228 				sprite->SetScale( scale, scale );
229 				sprite->SetZDepth( scale.v );
230 
231 				KrColorTransform color;
232 				int tint = CalculateTintFromScale( dScale );
233 
234 				color.Set( tint, 0, tint, 0, tint, 0, 255 );
235 				sprite->SetColor( color );
236 			}
237 		}
238 	}
239 
240 	engine->Draw();
241 }
242 
243 
GetY(int hIndex)244 int SinWaveTest::GetY( int hIndex )
245 {
246 	return ( hIndex + 1 ) * engine->ScreenBounds().Height() / ( ROWS + 1 );
247 }
248 
249 
GetX(int vIndex)250 int SinWaveTest::GetX( int vIndex )
251 {
252 	return ( vIndex + 1 ) * engine->ScreenBounds().Width() / ( ROWS + 1 );
253 }
254 
255